aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/os_darwin.h5
-rw-r--r--src/pkg/runtime/os_freebsd.h4
-rw-r--r--src/pkg/runtime/os_linux.h5
-rw-r--r--src/pkg/runtime/os_netbsd.h5
-rw-r--r--src/pkg/runtime/os_openbsd.h5
-rw-r--r--src/pkg/runtime/runtime.c2
-rw-r--r--src/pkg/runtime/runtime.h11
-rw-r--r--src/pkg/runtime/sig.go16
-rw-r--r--src/pkg/runtime/signal_darwin_386.c81
-rw-r--r--src/pkg/runtime/signal_darwin_amd64.c83
-rw-r--r--src/pkg/runtime/signal_freebsd_386.c75
-rw-r--r--src/pkg/runtime/signal_freebsd_amd64.c82
-rw-r--r--src/pkg/runtime/signal_linux_386.c82
-rw-r--r--src/pkg/runtime/signal_linux_amd64.c77
-rw-r--r--src/pkg/runtime/signal_linux_arm.c60
-rw-r--r--src/pkg/runtime/signal_netbsd_386.c83
-rw-r--r--src/pkg/runtime/signal_netbsd_amd64.c84
-rw-r--r--src/pkg/runtime/signal_openbsd_386.c83
-rw-r--r--src/pkg/runtime/signal_openbsd_amd64.c84
-rw-r--r--src/pkg/runtime/signal_unix.c60
-rw-r--r--src/pkg/runtime/signal_windows_386.c2
-rw-r--r--src/pkg/runtime/signal_windows_amd64.c2
-rw-r--r--src/pkg/runtime/signals_darwin.h73
-rw-r--r--src/pkg/runtime/signals_freebsd.h83
-rw-r--r--src/pkg/runtime/signals_linux.h106
-rw-r--r--src/pkg/runtime/signals_netbsd.h83
-rw-r--r--src/pkg/runtime/signals_openbsd.h83
-rw-r--r--src/pkg/runtime/sigqueue.goc106
-rw-r--r--src/pkg/runtime/sys_linux_386.s3
-rw-r--r--src/pkg/runtime/sys_linux_amd64.s3
-rw-r--r--src/pkg/runtime/sys_linux_arm.s3
-rw-r--r--src/pkg/runtime/thread_plan9.c2
32 files changed, 539 insertions, 997 deletions
diff --git a/src/pkg/runtime/os_darwin.h b/src/pkg/runtime/os_darwin.h
index 3e96071ba3..0003b66c91 100644
--- a/src/pkg/runtime/os_darwin.h
+++ b/src/pkg/runtime/os_darwin.h
@@ -22,6 +22,8 @@ int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
struct Sigaction;
void runtime·sigaction(uintptr, struct Sigaction*, struct Sigaction*);
+void runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
+void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
struct StackT;
void runtime·sigaltstack(struct StackT*, struct StackT*);
@@ -30,3 +32,6 @@ void runtime·sigpanic(void);
void runtime·setitimer(int32, Itimerval*, Itimerval*);
void runtime·raisesigpipe(void);
+
+#define NSIG 32
+#define SI_USER 0 /* empirically true, but not what headers say */
diff --git a/src/pkg/runtime/os_freebsd.h b/src/pkg/runtime/os_freebsd.h
index 8ef4c39877..18adab4554 100644
--- a/src/pkg/runtime/os_freebsd.h
+++ b/src/pkg/runtime/os_freebsd.h
@@ -6,8 +6,12 @@ void runtime·sigpanic(void);
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
struct sigaction;
void runtime·sigaction(int32, struct sigaction*, struct sigaction*);
+void runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
void runtiem·setitimerval(int32, Itimerval*, Itimerval*);
void runtime·setitimer(int32, Itimerval*, Itimerval*);
int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
void runtime·raisesigpipe(void);
+
+#define NSIG 33
+#define SI_USER 0
diff --git a/src/pkg/runtime/os_linux.h b/src/pkg/runtime/os_linux.h
index 0bb8d03392..82498c9888 100644
--- a/src/pkg/runtime/os_linux.h
+++ b/src/pkg/runtime/os_linux.h
@@ -11,9 +11,14 @@ int32 runtime·clone(int32, void*, M*, G*, void(*)(void));
struct Sigaction;
void runtime·rt_sigaction(uintptr, struct Sigaction*, void*, uintptr);
+void runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
+void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
void runtime·sigpanic(void);
void runtime·setitimer(int32, Itimerval*, Itimerval*);
void runtime·raisesigpipe(void);
+
+#define NSIG 65
+#define SI_USER 0
diff --git a/src/pkg/runtime/os_netbsd.h b/src/pkg/runtime/os_netbsd.h
index cf35402cac..67c58ecb2a 100644
--- a/src/pkg/runtime/os_netbsd.h
+++ b/src/pkg/runtime/os_netbsd.h
@@ -10,8 +10,13 @@ struct sigaction;
void runtime·sigpanic(void);
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
void runtime·sigaction(int32, struct sigaction*, struct sigaction*);
+void runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
+void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
void runtime·setitimerval(int32, Itimerval*, Itimerval*);
void runtime·setitimer(int32, Itimerval*, Itimerval*);
int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
void runtime·raisesigpipe(void);
+
+#define NSIG 33
+#define SI_USER 0
diff --git a/src/pkg/runtime/os_openbsd.h b/src/pkg/runtime/os_openbsd.h
index cf35402cac..67c58ecb2a 100644
--- a/src/pkg/runtime/os_openbsd.h
+++ b/src/pkg/runtime/os_openbsd.h
@@ -10,8 +10,13 @@ struct sigaction;
void runtime·sigpanic(void);
void runtime·sigaltstack(Sigaltstack*, Sigaltstack*);
void runtime·sigaction(int32, struct sigaction*, struct sigaction*);
+void runtime·setsig(int32, void(*)(int32, Siginfo*, void*, G*), bool);
+void runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp);
void runtime·setitimerval(int32, Itimerval*, Itimerval*);
void runtime·setitimer(int32, Itimerval*, Itimerval*);
int32 runtime·sysctl(uint32*, uint32, byte*, uintptr*, byte*, uintptr);
void runtime·raisesigpipe(void);
+
+#define NSIG 33
+#define SI_USER 0
diff --git a/src/pkg/runtime/runtime.c b/src/pkg/runtime/runtime.c
index 81caccad31..afe8c5abeb 100644
--- a/src/pkg/runtime/runtime.c
+++ b/src/pkg/runtime/runtime.c
@@ -343,7 +343,7 @@ runtime·check(void)
if(!(i != i1))
runtime·throw("float32nan3");
- runtime·initsig(0);
+ runtime·initsig();
}
void
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index b29487eb1f..8ac6c7eddb 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -267,11 +267,10 @@ struct SigTab
};
enum
{
- SigCatch = 1<<0,
- SigIgnore = 1<<1,
- SigRestart = 1<<2,
- SigQueue = 1<<3,
- SigPanic = 1<<4,
+ SigNotify = 1<<0, // let signal.Notify have signal, even if from kernel
+ SigKill = 1<<1, // if signal.Notify doesn't take it, exit quietly
+ SigThrow = 1<<2, // if signal.Notify doesn't take it, exit loudly
+ SigPanic = 1<<3, // if the signal is from the kernel, panic
};
// NOTE(rsc): keep in sync with extern.go:/type.Func.
@@ -501,7 +500,7 @@ String runtime·gostringn(byte*, int32);
Slice runtime·gobytes(byte*, int32);
String runtime·gostringnocopy(byte*);
String runtime·gostringw(uint16*);
-void runtime·initsig(int32);
+void runtime·initsig(void);
int32 runtime·gotraceback(void);
void runtime·goroutineheader(G*);
void runtime·traceback(uint8 *pc, uint8 *sp, uint8 *lr, G* gp);
diff --git a/src/pkg/runtime/sig.go b/src/pkg/runtime/sig.go
deleted file mode 100644
index 6d560b9007..0000000000
--- a/src/pkg/runtime/sig.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-// Sigrecv returns a bitmask of signals that have arrived since the last call to Sigrecv.
-// It blocks until at least one signal arrives.
-func Sigrecv() uint32
-
-// Signame returns a string describing the signal, or "" if the signal is unknown.
-func Signame(sig int32) string
-
-// Siginit enables receipt of signals via Sigrecv. It should typically
-// be called during initialization.
-func Siginit()
diff --git a/src/pkg/runtime/signal_darwin_386.c b/src/pkg/runtime/signal_darwin_386.c
index 14f99115b4..803bd242f3 100644
--- a/src/pkg/runtime/signal_darwin_386.c
+++ b/src/pkg/runtime/signal_darwin_386.c
@@ -25,14 +25,6 @@ runtime·dumpregs(Regs32 *r)
runtime·printf("gs %x\n", r->gs);
}
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
@@ -41,6 +33,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
Regs32 *r;
uintptr *sp;
byte *pc;
+ SigTab *t;
uc = context;
mc = uc->uc_mcontext;
@@ -51,7 +44,10 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Work around Leopard bug that doesn't set FPE_INTDIV.
// Look at instruction to see if it is a divide.
// Not necessary in Snow Leopard (si_code will be != 0).
@@ -87,12 +83,15 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -116,11 +115,6 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
}
void
-runtime·sigignore(int32, Siginfo*, void*)
-{
-}
-
-void
runtime·signalstack(byte *p, int32 n)
{
StackT st;
@@ -131,8 +125,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -145,50 +139,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
*(uintptr*)sa.__sigaction_u = (uintptr)fn;
runtime·sigaction(i, &sa, nil);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_darwin_amd64.c b/src/pkg/runtime/signal_darwin_amd64.c
index c7621ddcaf..0c954294a5 100644
--- a/src/pkg/runtime/signal_darwin_amd64.c
+++ b/src/pkg/runtime/signal_darwin_amd64.c
@@ -33,14 +33,6 @@ runtime·dumpregs(Regs64 *r)
runtime·printf("gs %X\n", r->gs);
}
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
@@ -49,6 +41,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
Regs64 *r;
uintptr *sp;
byte *pc;
+ SigTab *t;
uc = context;
mc = uc->uc_mcontext;
@@ -59,7 +52,10 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Work around Leopard bug that doesn't set FPE_INTDIV.
// Look at instruction to see if it is a divide.
// Not necessary in Snow Leopard (si_code will be != 0).
@@ -96,13 +92,16 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
r->rip = (uintptr)runtime·sigpanic;
return;
}
-
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
+
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -126,11 +125,6 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
}
void
-runtime·sigignore(int32, Siginfo*, void*)
-{
-}
-
-void
runtime·signalstack(byte *p, int32 n)
{
StackT st;
@@ -141,8 +135,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -155,50 +149,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
*(uintptr*)sa.__sigaction_u = (uintptr)fn;
runtime·sigaction(i, &sa, nil);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_freebsd_386.c b/src/pkg/runtime/signal_freebsd_386.c
index ff4aaabdb5..c6eb344361 100644
--- a/src/pkg/runtime/signal_freebsd_386.c
+++ b/src/pkg/runtime/signal_freebsd_386.c
@@ -50,6 +50,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
Ucontext *uc;
Mcontext *r;
uintptr *sp;
+ SigTab *t;
uc = context;
r = &uc->uc_mcontext;
@@ -59,7 +60,10 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Make it look like a call to the signal func.
// Have to pass arguments out of band since
// augmenting the stack frame would break
@@ -84,12 +88,15 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -111,13 +118,6 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
runtime·exit(2);
}
-// Called from kernel on signal stack, so no stack split.
-#pragma textflag 7
-void
-runtime·sigignore(void)
-{
-}
-
void
runtime·signalstack(byte *p, int32 n)
{
@@ -129,8 +129,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -144,50 +144,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
sa.__sigaction_u.__sa_sigaction = (void*)fn;
runtime·sigaction(i, &sa, nil);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_freebsd_amd64.c b/src/pkg/runtime/signal_freebsd_amd64.c
index 2683f4fd09..d307d726de 100644
--- a/src/pkg/runtime/signal_freebsd_amd64.c
+++ b/src/pkg/runtime/signal_freebsd_amd64.c
@@ -44,14 +44,6 @@ runtime·dumpregs(Mcontext *r)
runtime·printf("gs %X\n", r->mc_gs);
}
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
@@ -67,7 +59,10 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Make it look like a call to the signal func.
// Have to pass arguments out of band since
// augmenting the stack frame would break
@@ -92,12 +87,15 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -119,13 +117,6 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
runtime·exit(2);
}
-// Called from kernel on signal stack, so no stack split.
-#pragma textflag 7
-void
-runtime·sigignore(void)
-{
-}
-
void
runtime·signalstack(byte *p, int32 n)
{
@@ -137,8 +128,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -152,50 +143,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
sa.__sigaction_u.__sa_sigaction = (void*)fn;
runtime·sigaction(i, &sa, nil);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_linux_386.c b/src/pkg/runtime/signal_linux_386.c
index 4f3abcebb3..b43dbc1121 100644
--- a/src/pkg/runtime/signal_linux_386.c
+++ b/src/pkg/runtime/signal_linux_386.c
@@ -30,23 +30,15 @@ runtime·dumpregs(Sigcontext *r)
* and calls sighandler().
*/
extern void runtime·sigtramp(void);
-extern void runtime·sigignore(void); // just returns
extern void runtime·sigreturn(void); // calls runtime·sigreturn
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
Ucontext *uc;
Sigcontext *r;
uintptr *sp;
+ SigTab *t;
uc = context;
r = &uc->uc_mcontext;
@@ -56,7 +48,10 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Make it look like a call to the signal func.
// Have to pass arguments out of band since
// augmenting the stack frame would break
@@ -81,12 +76,15 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -119,8 +117,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -136,59 +134,13 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
runtime·rt_sigaction(i, &sa, nil, 8);
}
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
-
#define AT_NULL 0
#define AT_SYSINFO 32
extern uint32 runtime·_vdso;
#pragma textflag 7
-void runtime·linux_setup_vdso(int32 argc, void *argv_list)
+void
+runtime·linux_setup_vdso(int32 argc, void *argv_list)
{
byte **argv = &argv_list;
byte **envp;
@@ -204,5 +156,5 @@ void runtime·linux_setup_vdso(int32 argc, void *argv_list)
runtime·_vdso = auxv[1];
break;
}
- }
+ }
}
diff --git a/src/pkg/runtime/signal_linux_amd64.c b/src/pkg/runtime/signal_linux_amd64.c
index 937d5c3478..551744b78d 100644
--- a/src/pkg/runtime/signal_linux_amd64.c
+++ b/src/pkg/runtime/signal_linux_amd64.c
@@ -38,17 +38,8 @@ runtime·dumpregs(Sigcontext *r)
* and calls sighandler().
*/
extern void runtime·sigtramp(void);
-extern void runtime·sigignore(void); // just returns
extern void runtime·sigreturn(void); // calls runtime·sigreturn
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
@@ -56,6 +47,7 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
Mcontext *mc;
Sigcontext *r;
uintptr *sp;
+ SigTab *t;
uc = context;
mc = &uc->uc_mcontext;
@@ -66,7 +58,10 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Make it look like a call to the signal func.
// Have to pass arguments out of band since
// augmenting the stack frame would break
@@ -91,12 +86,15 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -129,8 +127,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -145,50 +143,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
sa.sa_handler = fn;
runtime·rt_sigaction(i, &sa, nil, 8);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_linux_arm.c b/src/pkg/runtime/signal_linux_arm.c
index b32ec7a226..a0905d3c52 100644
--- a/src/pkg/runtime/signal_linux_arm.c
+++ b/src/pkg/runtime/signal_linux_arm.c
@@ -38,17 +38,8 @@ runtime·dumpregs(Sigcontext *r)
* and calls sighandler().
*/
extern void runtime·sigtramp(void);
-extern void runtime·sigignore(void); // just returns
extern void runtime·sigreturn(void); // calls runtime·sigreturn
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
@@ -124,8 +115,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -140,50 +131,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
sa.sa_handler = fn;
runtime·rt_sigaction(i, &sa, nil, 8);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_netbsd_386.c b/src/pkg/runtime/signal_netbsd_386.c
index 74fa1d490b..739b359ee6 100644
--- a/src/pkg/runtime/signal_netbsd_386.c
+++ b/src/pkg/runtime/signal_netbsd_386.c
@@ -36,26 +36,22 @@ runtime·dumpregs(Sigcontext *r)
runtime·printf("gs %x\n", r->sc_gs);
}
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
Sigcontext *r = context;
uintptr *sp;
+ SigTab *t;
if(sig == SIGPROF) {
runtime·sigprof((uint8*)r->sc_eip, (uint8*)r->sc_esp, nil, gp);
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Make it look like a call to the signal func.
// Have to pass arguments out of band since
// augmenting the stack frame would break
@@ -80,12 +76,15 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -107,13 +106,6 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
runtime·exit(2);
}
-// Called from kernel on signal stack, so no stack split.
-#pragma textflag 7
-void
-runtime·sigignore(void)
-{
-}
-
void
runtime·signalstack(byte *p, int32 n)
{
@@ -125,8 +117,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -140,50 +132,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
sa.__sigaction_u.__sa_sigaction = (void*)fn;
runtime·sigaction(i, &sa, nil);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_netbsd_amd64.c b/src/pkg/runtime/signal_netbsd_amd64.c
index 6c69fa7339..e71f23551d 100644
--- a/src/pkg/runtime/signal_netbsd_amd64.c
+++ b/src/pkg/runtime/signal_netbsd_amd64.c
@@ -44,19 +44,12 @@ runtime·dumpregs(Sigcontext *r)
runtime·printf("gs %X\n", r->sc_gs);
}
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
Sigcontext *r = context;
uintptr *sp;
+ SigTab *t;
if(sig == SIGPROF) {
runtime·sigprof((uint8*)r->sc_rip,
@@ -64,7 +57,10 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Make it look like a call to the signal func.
// Have to pass arguments out of band since
// augmenting the stack frame would break
@@ -89,13 +85,15 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig)
- || (runtime·sigtab[sig].flags & SigIgnore))
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -117,13 +115,6 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
runtime·exit(2);
}
-// Called from kernel on signal stack, so no stack split.
-#pragma textflag 7
-void
-runtime·sigignore(void)
-{
-}
-
void
runtime·signalstack(byte *p, int32 n)
{
@@ -135,8 +126,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -150,50 +141,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
sa.__sigaction_u.__sa_sigaction = (void*)fn;
runtime·sigaction(i, &sa, nil);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_openbsd_386.c b/src/pkg/runtime/signal_openbsd_386.c
index 74fa1d490b..739b359ee6 100644
--- a/src/pkg/runtime/signal_openbsd_386.c
+++ b/src/pkg/runtime/signal_openbsd_386.c
@@ -36,26 +36,22 @@ runtime·dumpregs(Sigcontext *r)
runtime·printf("gs %x\n", r->sc_gs);
}
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
Sigcontext *r = context;
uintptr *sp;
+ SigTab *t;
if(sig == SIGPROF) {
runtime·sigprof((uint8*)r->sc_eip, (uint8*)r->sc_esp, nil, gp);
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Make it look like a call to the signal func.
// Have to pass arguments out of band since
// augmenting the stack frame would break
@@ -80,12 +76,15 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -107,13 +106,6 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
runtime·exit(2);
}
-// Called from kernel on signal stack, so no stack split.
-#pragma textflag 7
-void
-runtime·sigignore(void)
-{
-}
-
void
runtime·signalstack(byte *p, int32 n)
{
@@ -125,8 +117,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -140,50 +132,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
sa.__sigaction_u.__sa_sigaction = (void*)fn;
runtime·sigaction(i, &sa, nil);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_openbsd_amd64.c b/src/pkg/runtime/signal_openbsd_amd64.c
index 6c69fa7339..e71f23551d 100644
--- a/src/pkg/runtime/signal_openbsd_amd64.c
+++ b/src/pkg/runtime/signal_openbsd_amd64.c
@@ -44,19 +44,12 @@ runtime·dumpregs(Sigcontext *r)
runtime·printf("gs %X\n", r->sc_gs);
}
-String
-runtime·signame(int32 sig)
-{
- if(sig < 0 || sig >= NSIG)
- return runtime·emptystring;
- return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
-}
-
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
Sigcontext *r = context;
uintptr *sp;
+ SigTab *t;
if(sig == SIGPROF) {
runtime·sigprof((uint8*)r->sc_rip,
@@ -64,7 +57,10 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
+ t = &runtime·sigtab[sig];
+ if(info->si_code != SI_USER && (t->flags & SigPanic)) {
+ if(gp == nil)
+ goto Throw;
// Make it look like a call to the signal func.
// Have to pass arguments out of band since
// augmenting the stack frame would break
@@ -89,13 +85,15 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
return;
}
- if(runtime·sigtab[sig].flags & SigQueue) {
- if(runtime·sigsend(sig)
- || (runtime·sigtab[sig].flags & SigIgnore))
+ if(info->si_code == SI_USER || (t->flags & SigNotify))
+ if(runtime·sigsend(sig))
return;
- runtime·exit(2); // SIGINT, SIGTERM, etc
- }
+ if(t->flags & SigKill)
+ runtime·exit(2);
+ if(!(t->flags & SigThrow))
+ return;
+Throw:
if(runtime·panicking) // traceback already printed
runtime·exit(2);
runtime·panicking = 1;
@@ -117,13 +115,6 @@ runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
runtime·exit(2);
}
-// Called from kernel on signal stack, so no stack split.
-#pragma textflag 7
-void
-runtime·sigignore(void)
-{
-}
-
void
runtime·signalstack(byte *p, int32 n)
{
@@ -135,8 +126,8 @@ runtime·signalstack(byte *p, int32 n)
runtime·sigaltstack(&st, nil);
}
-static void
-sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
+void
+runtime·setsig(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
{
Sigaction sa;
@@ -150,50 +141,3 @@ sigaction(int32 i, void (*fn)(int32, Siginfo*, void*, G*), bool restart)
sa.__sigaction_u.__sa_sigaction = (void*)fn;
runtime·sigaction(i, &sa, nil);
}
-
-void
-runtime·initsig(int32 queue)
-{
- int32 i;
- void *fn;
-
- runtime·siginit();
-
- for(i = 0; i<NSIG; i++) {
- if(runtime·sigtab[i].flags) {
- if((runtime·sigtab[i].flags & SigQueue) != queue)
- continue;
- if(runtime·sigtab[i].flags & (SigCatch | SigQueue))
- fn = runtime·sighandler;
- else
- fn = runtime·sigignore;
- sigaction(i, fn, (runtime·sigtab[i].flags & SigRestart) != 0);
- }
- }
-}
-
-void
-runtime·resetcpuprofiler(int32 hz)
-{
- Itimerval it;
-
- runtime·memclr((byte*)&it, sizeof it);
- if(hz == 0) {
- runtime·setitimer(ITIMER_PROF, &it, nil);
- sigaction(SIGPROF, SIG_IGN, true);
- } else {
- sigaction(SIGPROF, runtime·sighandler, true);
- it.it_interval.tv_sec = 0;
- it.it_interval.tv_usec = 1000000 / hz;
- it.it_value = it.it_interval;
- runtime·setitimer(ITIMER_PROF, &it, nil);
- }
- m->profilehz = hz;
-}
-
-void
-os·sigpipe(void)
-{
- sigaction(SIGPIPE, SIG_DFL, false);
- runtime·raisesigpipe();
-}
diff --git a/src/pkg/runtime/signal_unix.c b/src/pkg/runtime/signal_unix.c
new file mode 100644
index 0000000000..14ce1418f8
--- /dev/null
+++ b/src/pkg/runtime/signal_unix.c
@@ -0,0 +1,60 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin freebsd linux openbsd netbsd
+
+#include "runtime.h"
+#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
+
+extern SigTab runtime·sigtab[];
+
+String
+runtime·signame(int32 sig)
+{
+ if(sig < 0 || sig >= NSIG)
+ return runtime·emptystring;
+ return runtime·gostringnocopy((byte*)runtime·sigtab[sig].name);
+}
+
+void
+runtime·initsig(void)
+{
+ int32 i;
+ SigTab *t;
+
+ // First call: basic setup.
+ for(i = 0; i<NSIG; i++) {
+ t = &runtime·sigtab[i];
+ if(t->flags == 0)
+ continue;
+ runtime·setsig(i, runtime·sighandler, 1);
+ }
+}
+
+void
+runtime·resetcpuprofiler(int32 hz)
+{
+ Itimerval it;
+
+ runtime·memclr((byte*)&it, sizeof it);
+ if(hz == 0) {
+ runtime·setitimer(ITIMER_PROF, &it, nil);
+ runtime·setsig(SIGPROF, SIG_IGN, true);
+ } else {
+ runtime·setsig(SIGPROF, runtime·sighandler, true);
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 1000000 / hz;
+ it.it_value = it.it_interval;
+ runtime·setitimer(ITIMER_PROF, &it, nil);
+ }
+ m->profilehz = hz;
+}
+
+void
+os·sigpipe(void)
+{
+ runtime·setsig(SIGPIPE, SIG_DFL, false);
+ runtime·raisesigpipe();
+}
diff --git a/src/pkg/runtime/signal_windows_386.c b/src/pkg/runtime/signal_windows_386.c
index 48d2a8bff9..c99f2a176e 100644
--- a/src/pkg/runtime/signal_windows_386.c
+++ b/src/pkg/runtime/signal_windows_386.c
@@ -25,7 +25,7 @@ runtime·dumpregs(Context *r)
}
void
-runtime·initsig(int32)
+runtime·initsig(void)
{
runtime·siginit();
}
diff --git a/src/pkg/runtime/signal_windows_amd64.c b/src/pkg/runtime/signal_windows_amd64.c
index 92cdb8054f..58d70a4089 100644
--- a/src/pkg/runtime/signal_windows_amd64.c
+++ b/src/pkg/runtime/signal_windows_amd64.c
@@ -35,7 +35,7 @@ runtime·dumpregs(Context *r)
}
void
-runtime·initsig(int32)
+runtime·initsig(void)
{
runtime·siginit();
// following line keeps sigtramp alive at link stage
diff --git a/src/pkg/runtime/signals_darwin.h b/src/pkg/runtime/signals_darwin.h
index 035027fadd..4ff08bcdc9 100644
--- a/src/pkg/runtime/signals_darwin.h
+++ b/src/pkg/runtime/signals_darwin.h
@@ -2,50 +2,47 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#define C SigCatch
-#define I SigIgnore
-#define R SigRestart
-#define Q SigQueue
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
#define P SigPanic
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
- /* 1 */ Q+R, "SIGHUP: terminal line hangup",
- /* 2 */ Q+R, "SIGINT: interrupt",
- /* 3 */ C, "SIGQUIT: quit",
- /* 4 */ C, "SIGILL: illegal instruction",
- /* 5 */ C, "SIGTRAP: trace trap", /* used by panic and array out of bounds, etc. */
- /* 6 */ C, "SIGABRT: abort",
- /* 7 */ C, "SIGEMT: emulate instruction executed",
- /* 8 */ C+P, "SIGFPE: floating-point exception",
+ /* 1 */ N+K, "SIGHUP: terminal line hangup",
+ /* 2 */ N+K, "SIGINT: interrupt",
+ /* 3 */ N+T, "SIGQUIT: quit",
+ /* 4 */ T, "SIGILL: illegal instruction",
+ /* 5 */ T, "SIGTRAP: trace trap",
+ /* 6 */ N+T, "SIGABRT: abort",
+ /* 7 */ T, "SIGEMT: emulate instruction executed",
+ /* 8 */ P, "SIGFPE: floating-point exception",
/* 9 */ 0, "SIGKILL: kill",
- /* 10 */ C+P, "SIGBUS: bus error",
- /* 11 */ C+P, "SIGSEGV: segmentation violation",
- /* 12 */ C, "SIGSYS: bad system call",
- /* 13 */ I, "SIGPIPE: write to broken pipe",
- /* 14 */ Q+I+R, "SIGALRM: alarm clock",
- /* 15 */ Q+R, "SIGTERM: termination",
- /* 16 */ Q+I+R, "SIGURG: urgent condition on socket",
+ /* 10 */ P, "SIGBUS: bus error",
+ /* 11 */ P, "SIGSEGV: segmentation violation",
+ /* 12 */ T, "SIGSYS: bad system call",
+ /* 13 */ N, "SIGPIPE: write to broken pipe",
+ /* 14 */ N, "SIGALRM: alarm clock",
+ /* 15 */ N+K, "SIGTERM: termination",
+ /* 16 */ N, "SIGURG: urgent condition on socket",
/* 17 */ 0, "SIGSTOP: stop",
- /* 18 */ Q+I+R, "SIGTSTP: keyboard stop",
+ /* 18 */ N, "SIGTSTP: keyboard stop",
/* 19 */ 0, "SIGCONT: continue after stop",
- /* 20 */ Q+I+R, "SIGCHLD: child status has changed",
- /* 21 */ Q+I+R, "SIGTTIN: background read from tty",
- /* 22 */ Q+I+R, "SIGTTOU: background write to tty",
- /* 23 */ Q+I+R, "SIGIO: i/o now possible",
- /* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
- /* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
- /* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
- /* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
- /* 28 */ Q+I+R, "SIGWINCH: window size change",
- /* 29 */ Q+I+R, "SIGINFO: status request from keyboard",
- /* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1",
- /* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2",
+ /* 20 */ N, "SIGCHLD: child status has changed",
+ /* 21 */ N, "SIGTTIN: background read from tty",
+ /* 22 */ N, "SIGTTOU: background write to tty",
+ /* 23 */ N, "SIGIO: i/o now possible",
+ /* 24 */ N, "SIGXCPU: cpu limit exceeded",
+ /* 25 */ N, "SIGXFSZ: file size limit exceeded",
+ /* 26 */ N, "SIGVTALRM: virtual alarm clock",
+ /* 27 */ N, "SIGPROF: profiling alarm clock",
+ /* 28 */ N, "SIGWINCH: window size change",
+ /* 29 */ N, "SIGINFO: status request from keyboard",
+ /* 30 */ N, "SIGUSR1: user-defined signal 1",
+ /* 31 */ N, "SIGUSR2: user-defined signal 2",
};
-#undef C
-#undef I
-#undef R
-#undef Q
-#undef P
-#define NSIG 32
+#undef N
+#undef K
+#undef T
+#undef P
diff --git a/src/pkg/runtime/signals_freebsd.h b/src/pkg/runtime/signals_freebsd.h
index 63a84671d9..6a15017325 100644
--- a/src/pkg/runtime/signals_freebsd.h
+++ b/src/pkg/runtime/signals_freebsd.h
@@ -2,51 +2,48 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#define C SigCatch
-#define I SigIgnore
-#define R SigRestart
-#define Q SigQueue
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
#define P SigPanic
SigTab runtime·sigtab[] = {
- /* 0 */ 0, "SIGNONE: no trap",
- /* 1 */ Q+R, "SIGHUP: terminal line hangup",
- /* 2 */ Q+R, "SIGINT: interrupt",
- /* 3 */ C, "SIGQUIT: quit",
- /* 4 */ C, "SIGILL: illegal instruction",
- /* 5 */ C, "SIGTRAP: trace trap",
- /* 6 */ C, "SIGABRT: abort",
- /* 7 */ C, "SIGEMT: EMT instruction",
- /* 8 */ C+P, "SIGFPE: floating-point exception",
- /* 9 */ 0, "SIGKILL: kill",
- /* 10 */ C+P, "SIGBUS: bus error",
- /* 11 */ C+P, "SIGSEGV: segmentation violation",
- /* 12 */ C, "SIGSYS: bad system call",
- /* 13 */ I, "SIGPIPE: write to broken pipe",
- /* 14 */ Q+I+R, "SIGALRM: alarm clock",
- /* 15 */ Q+R, "SIGTERM: termination",
- /* 16 */ Q+I+R, "SIGURG: urgent condition on socket",
- /* 17 */ 0, "SIGSTOP: stop, unblockable",
- /* 18 */ Q+I+R, "SIGTSTP: stop from tty",
- /* 19 */ 0, "SIGCONT: continue",
- /* 20 */ Q+I+R, "SIGCHLD: child status has changed",
- /* 21 */ Q+I+R, "SIGTTIN: background read from tty",
- /* 22 */ Q+I+R, "SIGTTOU: background write to tty",
- /* 23 */ Q+I+R, "SIGIO: i/o now possible",
- /* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
- /* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
- /* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
- /* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
- /* 28 */ Q+I+R, "SIGWINCH: window size change",
- /* 29 */ Q+I+R, "SIGINFO: information request",
- /* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1",
- /* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2",
- /* 32 */ Q+I+R, "SIGTHR: reserved",
+ /* 0 */ 0, "SIGNONE: no trap",
+ /* 1 */ N+K, "SIGHUP: terminal line hangup",
+ /* 2 */ N+K, "SIGINT: interrupt",
+ /* 3 */ N+T, "SIGQUIT: quit",
+ /* 4 */ T, "SIGILL: illegal instruction",
+ /* 5 */ T, "SIGTRAP: trace trap",
+ /* 6 */ N+T, "SIGABRT: abort",
+ /* 7 */ T, "SIGEMT: emulate instruction executed",
+ /* 8 */ P, "SIGFPE: floating-point exception",
+ /* 9 */ 0, "SIGKILL: kill",
+ /* 10 */ P, "SIGBUS: bus error",
+ /* 11 */ P, "SIGSEGV: segmentation violation",
+ /* 12 */ T, "SIGSYS: bad system call",
+ /* 13 */ N, "SIGPIPE: write to broken pipe",
+ /* 14 */ N, "SIGALRM: alarm clock",
+ /* 15 */ N+K, "SIGTERM: termination",
+ /* 16 */ N, "SIGURG: urgent condition on socket",
+ /* 17 */ 0, "SIGSTOP: stop",
+ /* 18 */ N, "SIGTSTP: keyboard stop",
+ /* 19 */ 0, "SIGCONT: continue after stop",
+ /* 20 */ N, "SIGCHLD: child status has changed",
+ /* 21 */ N, "SIGTTIN: background read from tty",
+ /* 22 */ N, "SIGTTOU: background write to tty",
+ /* 23 */ N, "SIGIO: i/o now possible",
+ /* 24 */ N, "SIGXCPU: cpu limit exceeded",
+ /* 25 */ N, "SIGXFSZ: file size limit exceeded",
+ /* 26 */ N, "SIGVTALRM: virtual alarm clock",
+ /* 27 */ N, "SIGPROF: profiling alarm clock",
+ /* 28 */ N, "SIGWINCH: window size change",
+ /* 29 */ N, "SIGINFO: status request from keyboard",
+ /* 30 */ N, "SIGUSR1: user-defined signal 1",
+ /* 31 */ N, "SIGUSR2: user-defined signal 2",
+ /* 32 */ N, "SIGTHR: reserved",
};
-#undef C
-#undef I
-#undef R
-#undef Q
-#undef P
-#define NSIG 33
+#undef N
+#undef K
+#undef T
+#undef P
diff --git a/src/pkg/runtime/signals_linux.h b/src/pkg/runtime/signals_linux.h
index 1fc5f8c87c..1df063a187 100644
--- a/src/pkg/runtime/signals_linux.h
+++ b/src/pkg/runtime/signals_linux.h
@@ -2,50 +2,80 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#define C SigCatch
-#define I SigIgnore
-#define R SigRestart
-#define Q SigQueue
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
#define P SigPanic
SigTab runtime·sigtab[] = {
/* 0 */ 0, "SIGNONE: no trap",
- /* 1 */ Q+R, "SIGHUP: terminal line hangup",
- /* 2 */ Q+R, "SIGINT: interrupt",
- /* 3 */ C, "SIGQUIT: quit",
- /* 4 */ C, "SIGILL: illegal instruction",
- /* 5 */ C, "SIGTRAP: trace trap",
- /* 6 */ C, "SIGABRT: abort",
- /* 7 */ C+P, "SIGBUS: bus error",
- /* 8 */ C+P, "SIGFPE: floating-point exception",
+ /* 1 */ N+K, "SIGHUP: terminal line hangup",
+ /* 2 */ N+K, "SIGINT: interrupt",
+ /* 3 */ N+T, "SIGQUIT: quit",
+ /* 4 */ T, "SIGILL: illegal instruction",
+ /* 5 */ T, "SIGTRAP: trace trap",
+ /* 6 */ N+T, "SIGABRT: abort",
+ /* 7 */ P, "SIGBUS: bus error",
+ /* 8 */ P, "SIGFPE: floating-point exception",
/* 9 */ 0, "SIGKILL: kill",
- /* 10 */ Q+I+R, "SIGUSR1: user-defined signal 1",
- /* 11 */ C+P, "SIGSEGV: segmentation violation",
- /* 12 */ Q+I+R, "SIGUSR2: user-defined signal 2",
- /* 13 */ I, "SIGPIPE: write to broken pipe",
- /* 14 */ Q+I+R, "SIGALRM: alarm clock",
- /* 15 */ Q+R, "SIGTERM: termination",
- /* 16 */ C, "SIGSTKFLT: stack fault",
- /* 17 */ Q+I+R, "SIGCHLD: child status has changed",
+ /* 10 */ N, "SIGUSR1: user-defined signal 1",
+ /* 11 */ P, "SIGSEGV: segmentation violation",
+ /* 12 */ N, "SIGUSR2: user-defined signal 2",
+ /* 13 */ N, "SIGPIPE: write to broken pipe",
+ /* 14 */ N, "SIGALRM: alarm clock",
+ /* 15 */ N+K, "SIGTERM: termination",
+ /* 16 */ T, "SIGSTKFLT: stack fault",
+ /* 17 */ N, "SIGCHLD: child status has changed",
/* 18 */ 0, "SIGCONT: continue",
/* 19 */ 0, "SIGSTOP: stop, unblockable",
- /* 20 */ Q+I+R, "SIGTSTP: keyboard stop",
- /* 21 */ Q+I+R, "SIGTTIN: background read from tty",
- /* 22 */ Q+I+R, "SIGTTOU: background write to tty",
- /* 23 */ Q+I+R, "SIGURG: urgent condition on socket",
- /* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
- /* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
- /* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
- /* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
- /* 28 */ Q+I+R, "SIGWINCH: window size change",
- /* 29 */ Q+I+R, "SIGIO: i/o now possible",
- /* 30 */ Q+I+R, "SIGPWR: power failure restart",
- /* 31 */ C, "SIGSYS: bad system call",
+ /* 20 */ N, "SIGTSTP: keyboard stop",
+ /* 21 */ N, "SIGTTIN: background read from tty",
+ /* 22 */ N, "SIGTTOU: background write to tty",
+ /* 23 */ N, "SIGURG: urgent condition on socket",
+ /* 24 */ N, "SIGXCPU: cpu limit exceeded",
+ /* 25 */ N, "SIGXFSZ: file size limit exceeded",
+ /* 26 */ N, "SIGVTALRM: virtual alarm clock",
+ /* 27 */ N, "SIGPROF: profiling alarm clock",
+ /* 28 */ N, "SIGWINCH: window size change",
+ /* 29 */ N, "SIGIO: i/o now possible",
+ /* 30 */ N, "SIGPWR: power failure restart",
+ /* 31 */ N, "SIGSYS: bad system call",
+ /* 32 */ N, "signal 32",
+ /* 33 */ N, "signal 33",
+ /* 34 */ N, "signal 34",
+ /* 35 */ N, "signal 35",
+ /* 36 */ N, "signal 36",
+ /* 37 */ N, "signal 37",
+ /* 38 */ N, "signal 38",
+ /* 39 */ N, "signal 39",
+ /* 40 */ N, "signal 40",
+ /* 41 */ N, "signal 41",
+ /* 42 */ N, "signal 42",
+ /* 43 */ N, "signal 43",
+ /* 44 */ N, "signal 44",
+ /* 45 */ N, "signal 45",
+ /* 46 */ N, "signal 46",
+ /* 47 */ N, "signal 47",
+ /* 48 */ N, "signal 48",
+ /* 49 */ N, "signal 49",
+ /* 50 */ N, "signal 50",
+ /* 51 */ N, "signal 51",
+ /* 52 */ N, "signal 52",
+ /* 53 */ N, "signal 53",
+ /* 54 */ N, "signal 54",
+ /* 55 */ N, "signal 55",
+ /* 56 */ N, "signal 56",
+ /* 57 */ N, "signal 57",
+ /* 58 */ N, "signal 58",
+ /* 59 */ N, "signal 59",
+ /* 60 */ N, "signal 60",
+ /* 61 */ N, "signal 61",
+ /* 62 */ N, "signal 62",
+ /* 63 */ N, "signal 63",
+ /* 64 */ N, "signal 64",
};
-#undef C
-#undef I
-#undef R
-#undef Q
-#undef P
-#define NSIG 32
+#undef N
+#undef K
+#undef T
+#undef P
diff --git a/src/pkg/runtime/signals_netbsd.h b/src/pkg/runtime/signals_netbsd.h
index 63a84671d9..6a15017325 100644
--- a/src/pkg/runtime/signals_netbsd.h
+++ b/src/pkg/runtime/signals_netbsd.h
@@ -2,51 +2,48 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#define C SigCatch
-#define I SigIgnore
-#define R SigRestart
-#define Q SigQueue
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
#define P SigPanic
SigTab runtime·sigtab[] = {
- /* 0 */ 0, "SIGNONE: no trap",
- /* 1 */ Q+R, "SIGHUP: terminal line hangup",
- /* 2 */ Q+R, "SIGINT: interrupt",
- /* 3 */ C, "SIGQUIT: quit",
- /* 4 */ C, "SIGILL: illegal instruction",
- /* 5 */ C, "SIGTRAP: trace trap",
- /* 6 */ C, "SIGABRT: abort",
- /* 7 */ C, "SIGEMT: EMT instruction",
- /* 8 */ C+P, "SIGFPE: floating-point exception",
- /* 9 */ 0, "SIGKILL: kill",
- /* 10 */ C+P, "SIGBUS: bus error",
- /* 11 */ C+P, "SIGSEGV: segmentation violation",
- /* 12 */ C, "SIGSYS: bad system call",
- /* 13 */ I, "SIGPIPE: write to broken pipe",
- /* 14 */ Q+I+R, "SIGALRM: alarm clock",
- /* 15 */ Q+R, "SIGTERM: termination",
- /* 16 */ Q+I+R, "SIGURG: urgent condition on socket",
- /* 17 */ 0, "SIGSTOP: stop, unblockable",
- /* 18 */ Q+I+R, "SIGTSTP: stop from tty",
- /* 19 */ 0, "SIGCONT: continue",
- /* 20 */ Q+I+R, "SIGCHLD: child status has changed",
- /* 21 */ Q+I+R, "SIGTTIN: background read from tty",
- /* 22 */ Q+I+R, "SIGTTOU: background write to tty",
- /* 23 */ Q+I+R, "SIGIO: i/o now possible",
- /* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
- /* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
- /* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
- /* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
- /* 28 */ Q+I+R, "SIGWINCH: window size change",
- /* 29 */ Q+I+R, "SIGINFO: information request",
- /* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1",
- /* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2",
- /* 32 */ Q+I+R, "SIGTHR: reserved",
+ /* 0 */ 0, "SIGNONE: no trap",
+ /* 1 */ N+K, "SIGHUP: terminal line hangup",
+ /* 2 */ N+K, "SIGINT: interrupt",
+ /* 3 */ N+T, "SIGQUIT: quit",
+ /* 4 */ T, "SIGILL: illegal instruction",
+ /* 5 */ T, "SIGTRAP: trace trap",
+ /* 6 */ N+T, "SIGABRT: abort",
+ /* 7 */ T, "SIGEMT: emulate instruction executed",
+ /* 8 */ P, "SIGFPE: floating-point exception",
+ /* 9 */ 0, "SIGKILL: kill",
+ /* 10 */ P, "SIGBUS: bus error",
+ /* 11 */ P, "SIGSEGV: segmentation violation",
+ /* 12 */ T, "SIGSYS: bad system call",
+ /* 13 */ N, "SIGPIPE: write to broken pipe",
+ /* 14 */ N, "SIGALRM: alarm clock",
+ /* 15 */ N+K, "SIGTERM: termination",
+ /* 16 */ N, "SIGURG: urgent condition on socket",
+ /* 17 */ 0, "SIGSTOP: stop",
+ /* 18 */ N, "SIGTSTP: keyboard stop",
+ /* 19 */ 0, "SIGCONT: continue after stop",
+ /* 20 */ N, "SIGCHLD: child status has changed",
+ /* 21 */ N, "SIGTTIN: background read from tty",
+ /* 22 */ N, "SIGTTOU: background write to tty",
+ /* 23 */ N, "SIGIO: i/o now possible",
+ /* 24 */ N, "SIGXCPU: cpu limit exceeded",
+ /* 25 */ N, "SIGXFSZ: file size limit exceeded",
+ /* 26 */ N, "SIGVTALRM: virtual alarm clock",
+ /* 27 */ N, "SIGPROF: profiling alarm clock",
+ /* 28 */ N, "SIGWINCH: window size change",
+ /* 29 */ N, "SIGINFO: status request from keyboard",
+ /* 30 */ N, "SIGUSR1: user-defined signal 1",
+ /* 31 */ N, "SIGUSR2: user-defined signal 2",
+ /* 32 */ N, "SIGTHR: reserved",
};
-#undef C
-#undef I
-#undef R
-#undef Q
-#undef P
-#define NSIG 33
+#undef N
+#undef K
+#undef T
+#undef P
diff --git a/src/pkg/runtime/signals_openbsd.h b/src/pkg/runtime/signals_openbsd.h
index 63a84671d9..6a15017325 100644
--- a/src/pkg/runtime/signals_openbsd.h
+++ b/src/pkg/runtime/signals_openbsd.h
@@ -2,51 +2,48 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-#define C SigCatch
-#define I SigIgnore
-#define R SigRestart
-#define Q SigQueue
+#define N SigNotify
+#define K SigKill
+#define T SigThrow
#define P SigPanic
SigTab runtime·sigtab[] = {
- /* 0 */ 0, "SIGNONE: no trap",
- /* 1 */ Q+R, "SIGHUP: terminal line hangup",
- /* 2 */ Q+R, "SIGINT: interrupt",
- /* 3 */ C, "SIGQUIT: quit",
- /* 4 */ C, "SIGILL: illegal instruction",
- /* 5 */ C, "SIGTRAP: trace trap",
- /* 6 */ C, "SIGABRT: abort",
- /* 7 */ C, "SIGEMT: EMT instruction",
- /* 8 */ C+P, "SIGFPE: floating-point exception",
- /* 9 */ 0, "SIGKILL: kill",
- /* 10 */ C+P, "SIGBUS: bus error",
- /* 11 */ C+P, "SIGSEGV: segmentation violation",
- /* 12 */ C, "SIGSYS: bad system call",
- /* 13 */ I, "SIGPIPE: write to broken pipe",
- /* 14 */ Q+I+R, "SIGALRM: alarm clock",
- /* 15 */ Q+R, "SIGTERM: termination",
- /* 16 */ Q+I+R, "SIGURG: urgent condition on socket",
- /* 17 */ 0, "SIGSTOP: stop, unblockable",
- /* 18 */ Q+I+R, "SIGTSTP: stop from tty",
- /* 19 */ 0, "SIGCONT: continue",
- /* 20 */ Q+I+R, "SIGCHLD: child status has changed",
- /* 21 */ Q+I+R, "SIGTTIN: background read from tty",
- /* 22 */ Q+I+R, "SIGTTOU: background write to tty",
- /* 23 */ Q+I+R, "SIGIO: i/o now possible",
- /* 24 */ Q+I+R, "SIGXCPU: cpu limit exceeded",
- /* 25 */ Q+I+R, "SIGXFSZ: file size limit exceeded",
- /* 26 */ Q+I+R, "SIGVTALRM: virtual alarm clock",
- /* 27 */ Q+I+R, "SIGPROF: profiling alarm clock",
- /* 28 */ Q+I+R, "SIGWINCH: window size change",
- /* 29 */ Q+I+R, "SIGINFO: information request",
- /* 30 */ Q+I+R, "SIGUSR1: user-defined signal 1",
- /* 31 */ Q+I+R, "SIGUSR2: user-defined signal 2",
- /* 32 */ Q+I+R, "SIGTHR: reserved",
+ /* 0 */ 0, "SIGNONE: no trap",
+ /* 1 */ N+K, "SIGHUP: terminal line hangup",
+ /* 2 */ N+K, "SIGINT: interrupt",
+ /* 3 */ N+T, "SIGQUIT: quit",
+ /* 4 */ T, "SIGILL: illegal instruction",
+ /* 5 */ T, "SIGTRAP: trace trap",
+ /* 6 */ N+T, "SIGABRT: abort",
+ /* 7 */ T, "SIGEMT: emulate instruction executed",
+ /* 8 */ P, "SIGFPE: floating-point exception",
+ /* 9 */ 0, "SIGKILL: kill",
+ /* 10 */ P, "SIGBUS: bus error",
+ /* 11 */ P, "SIGSEGV: segmentation violation",
+ /* 12 */ T, "SIGSYS: bad system call",
+ /* 13 */ N, "SIGPIPE: write to broken pipe",
+ /* 14 */ N, "SIGALRM: alarm clock",
+ /* 15 */ N+K, "SIGTERM: termination",
+ /* 16 */ N, "SIGURG: urgent condition on socket",
+ /* 17 */ 0, "SIGSTOP: stop",
+ /* 18 */ N, "SIGTSTP: keyboard stop",
+ /* 19 */ 0, "SIGCONT: continue after stop",
+ /* 20 */ N, "SIGCHLD: child status has changed",
+ /* 21 */ N, "SIGTTIN: background read from tty",
+ /* 22 */ N, "SIGTTOU: background write to tty",
+ /* 23 */ N, "SIGIO: i/o now possible",
+ /* 24 */ N, "SIGXCPU: cpu limit exceeded",
+ /* 25 */ N, "SIGXFSZ: file size limit exceeded",
+ /* 26 */ N, "SIGVTALRM: virtual alarm clock",
+ /* 27 */ N, "SIGPROF: profiling alarm clock",
+ /* 28 */ N, "SIGWINCH: window size change",
+ /* 29 */ N, "SIGINFO: status request from keyboard",
+ /* 30 */ N, "SIGUSR1: user-defined signal 1",
+ /* 31 */ N, "SIGUSR2: user-defined signal 2",
+ /* 32 */ N, "SIGTHR: reserved",
};
-#undef C
-#undef I
-#undef R
-#undef Q
-#undef P
-#define NSIG 33
+#undef N
+#undef K
+#undef T
+#undef P
diff --git a/src/pkg/runtime/sigqueue.goc b/src/pkg/runtime/sigqueue.goc
index 3c12e5caf5..e59b704fff 100644
--- a/src/pkg/runtime/sigqueue.goc
+++ b/src/pkg/runtime/sigqueue.goc
@@ -39,36 +39,33 @@
package runtime
#include "runtime.h"
#include "defs_GOOS_GOARCH.h"
+#include "os_GOOS.h"
static struct {
Note;
- uint32 mask;
+ uint32 mask[(NSIG+31)/32];
+ uint32 wanted[(NSIG+31)/32];
+ uint32 kick;
bool inuse;
} sig;
-void
-runtime·siginit(void)
-{
- runtime·noteclear(&sig);
-}
-
// Called from sighandler to send a signal back out of the signal handling thread.
bool
runtime·sigsend(int32 s)
{
uint32 bit, mask;
- if(!sig.inuse)
+ if(!sig.inuse || s < 0 || s >= 32*nelem(sig.wanted) || !(sig.wanted[s/32]&(1U<<(s&31))))
return false;
- bit = 1 << s;
+ bit = 1 << (s&31);
for(;;) {
- mask = sig.mask;
+ mask = sig.mask[s/32];
if(mask & bit)
break; // signal already in queue
- if(runtime·cas(&sig.mask, mask, mask|bit)) {
+ if(runtime·cas(&sig.mask[s/32], mask, mask|bit)) {
// Added to queue.
- // Only send a wakeup for the first signal in each round.
- if(mask == 0)
+ // Only send a wakeup if the receiver needs a kick.
+ if(runtime·cas(&sig.kick, 1, 0))
runtime·notewakeup(&sig);
break;
}
@@ -76,24 +73,77 @@ runtime·sigsend(int32 s)
return true;
}
-// Called to receive a bitmask of queued signals.
-func Sigrecv() (m uint32) {
- runtime·entersyscall();
- runtime·notesleep(&sig);
- runtime·exitsyscall();
- runtime·noteclear(&sig);
+// Called to receive the next queued signal.
+// Must only be called from a single goroutine at a time.
+func signal_recv() (m uint32) {
+ static uint32 recv[nelem(sig.mask)];
+ int32 i, more;
+
for(;;) {
- m = sig.mask;
- if(runtime·cas(&sig.mask, m, 0))
- break;
+ // Serve from local copy if there are bits left.
+ for(i=0; i<NSIG; i++) {
+ if(recv[i/32]&(1U<<(i&31))) {
+ recv[i/32] ^= 1U<<(i&31);
+ m = i;
+ goto done;
+ }
+ }
+
+ // Get a new local copy.
+ // Ask for a kick if more signals come in
+ // during or after our check (before the sleep).
+ if(sig.kick == 0) {
+ runtime·noteclear(&sig);
+ runtime·cas(&sig.kick, 0, 1);
+ }
+
+ more = 0;
+ for(i=0; i<nelem(sig.mask); i++) {
+ for(;;) {
+ m = sig.mask[i];
+ if(runtime·cas(&sig.mask[i], m, 0))
+ break;
+ }
+ recv[i] = m;
+ if(m != 0)
+ more = 1;
+ }
+ if(more)
+ continue;
+
+ // Sleep waiting for more.
+ runtime·entersyscall();
+ runtime·notesleep(&sig);
+ runtime·exitsyscall();
}
-}
-func Signame(sig int32) (name String) {
- name = runtime·signame(sig);
+done:;
+ // goc requires that we fall off the end of functions
+ // that return values instead of using our own return
+ // statements.
}
-func Siginit() {
- runtime·initsig(SigQueue);
- sig.inuse = true; // enable reception of signals; cannot disable
+// Must only be called from a single goroutine at a time.
+func signal_enable(s uint32) {
+ int32 i;
+
+ if(!sig.inuse) {
+ // The first call to signal_enable is for us
+ // to use for initialization. It does not pass
+ // signal information in m.
+ sig.inuse = true; // enable reception of signals; cannot disable
+ runtime·noteclear(&sig);
+ return;
+ }
+
+ if(~s == 0) {
+ // Special case: want everything.
+ for(i=0; i<nelem(sig.wanted); i++)
+ sig.wanted[i] = ~(uint32)0;
+ return;
+ }
+
+ if(s >= nelem(sig.wanted)*32)
+ return;
+ sig.wanted[s/32] |= 1U<<(s&31);
}
diff --git a/src/pkg/runtime/sys_linux_386.s b/src/pkg/runtime/sys_linux_386.s
index b745bc502e..bee785407f 100644
--- a/src/pkg/runtime/sys_linux_386.s
+++ b/src/pkg/runtime/sys_linux_386.s
@@ -175,9 +175,6 @@ TEXT runtime·sigtramp(SB),7,$44
RET
-TEXT runtime·sigignore(SB),7,$0
- RET
-
TEXT runtime·sigreturn(SB),7,$0
MOVL $173, AX // rt_sigreturn
// Sigreturn expects same SP as signal handler,
diff --git a/src/pkg/runtime/sys_linux_amd64.s b/src/pkg/runtime/sys_linux_amd64.s
index ef7bb2864c..68c2bf0eb7 100644
--- a/src/pkg/runtime/sys_linux_amd64.s
+++ b/src/pkg/runtime/sys_linux_amd64.s
@@ -157,9 +157,6 @@ TEXT runtime·sigtramp(SB),7,$64
MOVQ R10, g(BX)
RET
-TEXT runtime·sigignore(SB),7,$0
- RET
-
TEXT runtime·sigreturn(SB),7,$0
MOVL $15, AX // rt_sigreturn
SYSCALL
diff --git a/src/pkg/runtime/sys_linux_arm.s b/src/pkg/runtime/sys_linux_arm.s
index c3a828a924..8f30bff94b 100644
--- a/src/pkg/runtime/sys_linux_arm.s
+++ b/src/pkg/runtime/sys_linux_arm.s
@@ -271,9 +271,6 @@ TEXT runtime·sigaltstack(SB),7,$0
SWI $0
RET
-TEXT runtime·sigignore(SB),7,$0
- RET
-
TEXT runtime·sigtramp(SB),7,$24
// save g
MOVW g, R3
diff --git a/src/pkg/runtime/thread_plan9.c b/src/pkg/runtime/thread_plan9.c
index a9b156d028..1180fc880a 100644
--- a/src/pkg/runtime/thread_plan9.c
+++ b/src/pkg/runtime/thread_plan9.c
@@ -48,7 +48,7 @@ runtime·goenvs(void)
}
void
-runtime·initsig(int32)
+runtime·initsig(void)
{
}