[go] push by rsc@golang.org - os/signal: selective signal handling... on 2012-02-13 18:52 GMT

4 views
Skip to first unread message

g...@googlecode.com

unread,
Feb 13, 2012, 1:53:38 PM2/13/12
to golang-...@googlegroups.com
Revision: daf22f371d51
Author: Russ Cox <r...@golang.org>
Date: Mon Feb 13 10:52:37 2012
Log: os/signal: selective signal handling

Restore package os/signal, with new API:
Notify replaces Incoming, allowing clients
to ask for certain signals only. Also, signals
go to everyone who asks, not just one client.

This could plausibly move into package os now
that there are no magic side effects as a result
of the import.

Update runtime for new API: move common Unix
signal handling code into signal_unix.c.
(It's so easy to do this now that we don't have
to edit Makefiles!)

Tested on darwin,linux 386,amd64.

Fixes issue 1266.

R=r, dsymonds, bradfitz, iant, borman
CC=golang-dev
http://codereview.appspot.com/3749041
http://code.google.com/p/go/source/detail?r=daf22f371d51

Added:
/src/pkg/os/signal/sig.s
/src/pkg/os/signal/signal.go
/src/pkg/os/signal/signal_test.go
/src/pkg/os/signal/signal_unix.go
/src/pkg/runtime/signal_unix.c
Deleted:
/src/pkg/exp/signal/signal.go
/src/pkg/exp/signal/signal_test.go
/src/pkg/runtime/sig.go
Modified:
/doc/go1.html
/doc/go1.tmpl
/src/pkg/net/http/cgi/host_test.go
/src/pkg/os/exec.go
/src/pkg/os/exec_posix.go
/src/pkg/os/exec_unix.go
/src/pkg/os/exec_windows.go
/src/pkg/runtime/os_darwin.h
/src/pkg/runtime/os_freebsd.h
/src/pkg/runtime/os_linux.h
/src/pkg/runtime/os_netbsd.h
/src/pkg/runtime/os_openbsd.h
/src/pkg/runtime/runtime.c
/src/pkg/runtime/runtime.h
/src/pkg/runtime/signal_darwin_386.c
/src/pkg/runtime/signal_darwin_amd64.c
/src/pkg/runtime/signal_freebsd_386.c
/src/pkg/runtime/signal_freebsd_amd64.c
/src/pkg/runtime/signal_linux_386.c
/src/pkg/runtime/signal_linux_amd64.c
/src/pkg/runtime/signal_linux_arm.c
/src/pkg/runtime/signal_netbsd_386.c
/src/pkg/runtime/signal_netbsd_amd64.c
/src/pkg/runtime/signal_openbsd_386.c
/src/pkg/runtime/signal_openbsd_amd64.c
/src/pkg/runtime/signal_windows_386.c
/src/pkg/runtime/signal_windows_amd64.c
/src/pkg/runtime/signals_darwin.h
/src/pkg/runtime/signals_freebsd.h
/src/pkg/runtime/signals_linux.h
/src/pkg/runtime/signals_netbsd.h
/src/pkg/runtime/signals_openbsd.h
/src/pkg/runtime/sigqueue.goc
/src/pkg/runtime/sys_linux_386.s
/src/pkg/runtime/sys_linux_amd64.s
/src/pkg/runtime/sys_linux_arm.s
/src/pkg/runtime/thread_plan9.c
/src/pkg/syscall/mkerrors.sh
/src/pkg/syscall/syscall_bsd.go
/src/pkg/syscall/syscall_darwin.go
/src/pkg/syscall/syscall_linux.go
/src/pkg/syscall/syscall_unix.go
/src/pkg/syscall/zerrors_darwin_386.go
/src/pkg/syscall/zerrors_darwin_amd64.go
/src/pkg/syscall/zerrors_linux_386.go
/src/pkg/syscall/zerrors_linux_amd64.go
/src/pkg/syscall/zsyscall_freebsd_386.go
/src/pkg/syscall/zsyscall_freebsd_amd64.go
/src/pkg/syscall/zsyscall_linux_386.go
/src/pkg/syscall/zsyscall_linux_amd64.go
/src/pkg/syscall/zsyscall_linux_arm.go
/src/pkg/syscall/zsysnum_linux_386.go
/src/pkg/syscall/zsysnum_linux_amd64.go

=======================================
--- /dev/null
+++ /src/pkg/os/signal/sig.s Mon Feb 13 10:52:37 2012
@@ -0,0 +1,16 @@
+// 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.
+
+// Assembly to get into package runtime without using exported symbols.
+
+#ifdef GOARCH_arm
+#define JMP B
+#endif
+
+TEXT ·signal_enable(SB),7,$0
+ JMP runtime·signal_enable(SB)
+
+TEXT ·signal_recv(SB),7,$0
+ JMP runtime·signal_recv(SB)
+
=======================================
--- /dev/null
+++ /src/pkg/os/signal/signal.go Mon Feb 13 10:52:37 2012
@@ -0,0 +1,72 @@
+// 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.
+
+// Package signal implements access to incoming signals.
+package signal
+
+// BUG(rsc): This package is not yet implemented on Plan 9 and Windows.
+
+import (
+ "os"
+ "sync"
+)
+
+var handlers struct {
+ sync.Mutex
+ list []handler
+}
+
+type handler struct {
+ c chan<- os.Signal
+ sig os.Signal
+ all bool
+}
+
+// Notify causes package signal to relay incoming signals to c.
+// If no signals are listed, all incoming signals will be relayed to c.
+// Otherwise, just the listed signals will.
+//
+// Package signal will not block sending to c: the caller must ensure
+// that c has sufficient buffer space to keep up with the expected
+// signal rate. For a channel used for notification of just one signal
value,
+// a buffer of size 1 is sufficient.
+//
+func Notify(c chan<- os.Signal, sig ...os.Signal) {
+ if c == nil {
+ panic("os/signal: Notify using nil channel")
+ }
+
+ handlers.Lock()
+ defer handlers.Unlock()
+ if len(sig) == 0 {
+ enableSignal(nil)
+ handlers.list = append(handlers.list, handler{c: c, all: true})
+ } else {
+ for _, s := range sig {
+ // We use nil as a special wildcard value for enableSignal,
+ // so filter it out of the list of arguments. This is safe because
+ // we will never get an incoming nil signal, so discarding the
+ // registration cannot affect the observed behavior.
+ if s != nil {
+ enableSignal(s)
+ handlers.list = append(handlers.list, handler{c: c, sig: s})
+ }
+ }
+ }
+}
+
+func process(sig os.Signal) {
+ handlers.Lock()
+ defer handlers.Unlock()
+
+ for _, h := range handlers.list {
+ if h.all || h.sig == sig {
+ // send but do not block for it
+ select {
+ case h.c <- sig:
+ default:
+ }
+ }
+ }
+}
=======================================
--- /dev/null
+++ /src/pkg/os/signal/signal_test.go Mon Feb 13 10:52:37 2012
@@ -0,0 +1,60 @@
+// 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.
+
+// +build darwin freebsd linux netbsd openbsd
+
+package signal
+
+import (
+ "os"
+ "syscall"
+ "testing"
+ "time"
+)
+
+const sighup = syscall.SIGHUP
+
+func waitSig(t *testing.T, c <-chan os.Signal, sig os.Signal) {
+ select {
+ case s := <-c:
+ if s != sig {
+ t.Fatalf("signal was %v, want %v", s, sig)
+ }
+ case <-time.After(1 * time.Second):
+ t.Fatalf("timeout waiting for %v", sig)
+ }
+}
+
+func TestSignal(t *testing.T) {
+ // Ask for SIGHUP
+ c := make(chan os.Signal, 1)
+ Notify(c, sighup)
+
+ t.Logf("sighup...")
+ // Send this process a SIGHUP
+ syscall.Kill(syscall.Getpid(), sighup)
+ waitSig(t, c, sighup)
+
+ // Ask for everything we can get.
+ c1 := make(chan os.Signal, 1)
+ Notify(c1)
+
+ t.Logf("sigwinch...")
+ // Send this process a SIGWINCH
+ syscall.Kill(syscall.Getpid(), syscall.SIGWINCH)
+ waitSig(t, c1, syscall.SIGWINCH)
+
+ // Send two more SIGHUPs, to make sure that
+ // they get delivered on c1 and that not reading
+ // from c does not block everything.
+ t.Logf("sigwinch...")
+ syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
+ waitSig(t, c1, syscall.SIGHUP)
+ t.Logf("sigwinch...")
+ syscall.Kill(syscall.Getpid(), syscall.SIGHUP)
+ waitSig(t, c1, syscall.SIGHUP)
+
+ // The first SIGHUP should be waiting for us on c.
+ waitSig(t, c, syscall.SIGHUP)
+}
=======================================
--- /dev/null
+++ /src/pkg/os/signal/signal_unix.go Mon Feb 13 10:52:37 2012
@@ -0,0 +1,38 @@
+// 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 netbsd openbsd
+
+package signal
+
+import (
+ "os"
+ "syscall"
+)
+
+// In assembly.
+func signal_enable(uint32)
+func signal_recv() uint32
+
+func loop() {
+ for {
+ process(syscall.Signal(signal_recv()))
+ }
+}
+
+func init() {
+ signal_enable(0) // first call - initialize
+ go loop()
+}
+
+func enableSignal(sig os.Signal) {
+ switch sig := sig.(type) {
+ case nil:
+ signal_enable(^uint32(0))
+ case syscall.Signal:
+ signal_enable(uint32(sig))
+ default:
+ // Can ignore: this signal (whatever it is) will never come in.
+ }
+}
=======================================
--- /dev/null
+++ /src/pkg/runtime/signal_unix.c Mon Feb 13 10:52:37 2012
@@ -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();
+}
=======================================
--- /src/pkg/exp/signal/signal.go Wed Feb 1 14:08:50 2012
+++ /dev/null
@@ -1,37 +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.
-
-// +build darwin freebsd linux netbsd openbsd
-
-// Package signal implements operating system-independent signal handling.
-package signal
-
-import (
- "os"
- "runtime"
-)
-
-// Incoming is the global signal channel.
-// All signals received by the program will be delivered to this channel.
-var Incoming <-chan os.Signal
-
-func process(ch chan<- os.Signal) {
- for {
- var mask uint32 = runtime.Sigrecv()
- for sig := uint(0); sig < 32; sig++ {
- if mask&(1<<sig) != 0 {
- ch <- os.UnixSignal(sig)
- }
- }
- }
-}
-
-func init() {
- runtime.Siginit()
- ch := make(chan os.Signal) // Done here so Incoming can have type <-chan
Signal
- Incoming = ch
- go process(ch)
-}
-
-// BUG(rsc): This package is unavailable on Plan 9 and Windows.
=======================================
--- /src/pkg/exp/signal/signal_test.go Wed Feb 1 14:08:50 2012
+++ /dev/null
@@ -1,24 +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.
-
-// +build darwin freebsd linux netbsd openbsd
-
-package signal
-
-import (
- "os"
- "syscall"
- "testing"
-)
-
-const sighup = os.UnixSignal(syscall.SIGHUP)
-
-func TestSignal(t *testing.T) {
- // Send this process a SIGHUP.
- syscall.Syscall(syscall.SYS_KILL, uintptr(syscall.Getpid()),
syscall.SIGHUP, 0)
-
- if sig := (<-Incoming).(os.UnixSignal); sig != sighup {
- t.Errorf("signal was %v, want %v", sig, sighup)
- }
-}
=======================================
--- /src/pkg/runtime/sig.go Mon Jun 21 20:53:49 2010
+++ /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()
=======================================
--- /doc/go1.html Mon Feb 13 09:38:45 2012
+++ /doc/go1.html Mon Feb 13 10:52:37 2012
@@ -1363,6 +1363,39 @@
The compiler will catch code using the old interface.
</p>

+<h3 id="os/signal">The os/signal package</h3>
+
+<p>
+The <code>os/signal</code> package in Go 1 replaces the
+<code>Incoming</code> function, which returned a channel
+that received all incoming signals,
+with the selective <code>Notify</code> function, which asks
+for delivery of specific signals on an existing channel.
+</p>
+
+<p>
+<em>Updating</em>:
+Code must be updated by hand.
+A literal translation of
+</p>
+<pre>
+c := signal.Incoming()
+</pre>
+<p>
+is
+</p>
+<pre>
+c := make(chan os.Signal)
+signal.Notify(c) // ask for all signals
+</pre>
+<p>
+but most code should list the specific signals it wants to handle instead:
+</p>
+<pre>
+c := make(chan os.Signal)
+signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT)
+</pre>
+
<h3 id="runtime">The runtime package</h3>

<p>
=======================================
--- /doc/go1.tmpl Mon Feb 13 09:38:45 2012
+++ /doc/go1.tmpl Mon Feb 13 10:52:37 2012
@@ -1266,6 +1266,39 @@
The compiler will catch code using the old interface.
</p>

+<h3 id="os/signal">The os/signal package</h3>
+
+<p>
+The <code>os/signal</code> package in Go 1 replaces the
+<code>Incoming</code> function, which returned a channel
+that received all incoming signals,
+with the selective <code>Notify</code> function, which asks
+for delivery of specific signals on an existing channel.
+</p>
+
+<p>
+<em>Updating</em>:
+Code must be updated by hand.
+A literal translation of
+</p>
+<pre>
+c := signal.Incoming()
+</pre>
+<p>
+is
+</p>
+<pre>
+c := make(chan os.Signal)
+signal.Notify(c) // ask for all signals
+</pre>
+<p>
+but most code should list the specific signals it wants to handle instead:
+</p>
+<pre>
+c := make(chan os.Signal)
+signal.Notify(c, syscall.SIGHUP, syscall.SIGQUIT)
+</pre>
+
<h3 id="runtime">The runtime package</h3>

<p>
=======================================
--- /src/pkg/net/http/cgi/host_test.go Tue Jan 17 13:14:27 2012
+++ /src/pkg/net/http/cgi/host_test.go Mon Feb 13 10:52:37 2012
@@ -19,6 +19,7 @@
"runtime"
"strconv"
"strings"
+ "syscall"
"testing"
"time"
)
@@ -355,7 +356,7 @@
if err != nil {
return false
}
- return p.Signal(os.UnixSignal(0)) == nil
+ return p.Signal(syscall.Signal(0)) == nil
}

if !childRunning() {
=======================================
--- /src/pkg/os/exec.go Thu Feb 2 11:08:48 2012
+++ /src/pkg/os/exec.go Mon Feb 13 10:52:37 2012
@@ -46,10 +46,21 @@
Sys *syscall.SysProcAttr
}

-// A Signal can represent any operating system signal.
+// A Signal represents an operating system signal.
+// The usual underlying implementation is operating system-dependent:
+// on Unix it is syscall.Signal.
type Signal interface {
String() string
-}
+ Signal() // to distinguish from other Stringers
+}
+
+// The only signal values guaranteed to be present on all systems
+// are Interrupt (send the process an interrupt) and
+// Kill (force the process to exit).
+var (
+ Interrupt Signal = syscall.SIGINT
+ Kill Signal = syscall.SIGKILL
+)

// Getpid returns the process id of the caller.
func Getpid() int { return syscall.Getpid() }
=======================================
--- /src/pkg/os/exec_posix.go Fri Feb 10 13:47:19 2012
+++ /src/pkg/os/exec_posix.go Mon Feb 13 10:52:37 2012
@@ -7,19 +7,8 @@
package os

import (
- "runtime"
"syscall"
)
-
-type UnixSignal int32
-
-func (sig UnixSignal) String() string {
- s := runtime.Signame(int32(sig))
- if len(s) > 0 {
- return s
- }
- return "UnixSignal"
-}

// StartProcess starts a new process with the program, arguments and
attributes
// specified by name, argv and attr.
@@ -50,7 +39,7 @@

// Kill causes the Process to exit immediately.
func (p *Process) Kill() error {
- return p.Signal(UnixSignal(syscall.SIGKILL))
+ return p.Signal(Kill)
}

// TODO(rsc): Should os implement its own syscall.WaitStatus
@@ -118,9 +107,9 @@
case w.Exited():
res = "exit status " + itod(w.ExitStatus())
case w.Signaled():
- res = "signal " + itod(w.Signal())
+ res = "signal " + itod(int(w.Signal()))
case w.Stopped():
- res = "stop signal " + itod(w.StopSignal())
+ res = "stop signal " + itod(int(w.StopSignal()))
if w.StopSignal() == syscall.SIGTRAP && w.TrapCause() != 0 {
res += " (trap " + itod(w.TrapCause()) + ")"
}
=======================================
--- /src/pkg/os/exec_unix.go Mon Jan 16 21:51:54 2012
+++ /src/pkg/os/exec_unix.go Mon Feb 13 10:52:37 2012
@@ -57,7 +57,11 @@
if p.done {
return errors.New("os: process already finished")
}
- if e := syscall.Kill(p.Pid, int(sig.(UnixSignal))); e != nil {
+ s, ok := sig.(syscall.Signal)
+ if !ok {
+ return errors.New("os: unsupported signal type")
+ }
+ if e := syscall.Kill(p.Pid, s); e != nil {
return e
}
return nil
=======================================
--- /src/pkg/os/exec_windows.go Thu Feb 2 15:12:25 2012
+++ /src/pkg/os/exec_windows.go Mon Feb 13 10:52:37 2012
@@ -37,10 +37,11 @@
if p.done {
return errors.New("os: process already finished")
}
- if us, ok := sig.(UnixSignal); ok && us == syscall.SIGKILL {
+ if sig == Kill {
e := syscall.TerminateProcess(syscall.Handle(p.handle), 1)
return NewSyscallError("TerminateProcess", e)
}
+ // TODO(rsc): Handle Interrupt too?
return syscall.Errno(syscall.EWINDOWS)
}

=======================================
--- /src/pkg/runtime/os_darwin.h Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/os_darwin.h Mon Feb 13 10:52:37 2012
@@ -22,6 +22,8 @@

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·setitimer(int32, Itimerval*, Itimerval*);

void runtime·raisesigpipe(void);
+
+#define NSIG 32
+#define SI_USER 0 /* empirically true, but not what headers say */
=======================================
--- /src/pkg/runtime/os_freebsd.h Mon Jan 9 22:39:17 2012
+++ /src/pkg/runtime/os_freebsd.h Mon Feb 13 10:52:37 2012
@@ -6,8 +6,12 @@
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
=======================================
--- /src/pkg/runtime/os_linux.h Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/os_linux.h Mon Feb 13 10:52:37 2012
@@ -11,9 +11,14 @@

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
=======================================
--- /src/pkg/runtime/os_netbsd.h Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/os_netbsd.h Mon Feb 13 10:52:37 2012
@@ -10,8 +10,13 @@
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
=======================================
--- /src/pkg/runtime/os_openbsd.h Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/os_openbsd.h Mon Feb 13 10:52:37 2012
@@ -10,8 +10,13 @@
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
=======================================
--- /src/pkg/runtime/runtime.c Thu Jan 26 13:25:07 2012
+++ /src/pkg/runtime/runtime.c Mon Feb 13 10:52:37 2012
@@ -343,7 +343,7 @@
if(!(i != i1))
runtime·throw("float32nan3");

- runtime·initsig(0);
+ runtime·initsig();
}

void
=======================================
--- /src/pkg/runtime/runtime.h Sun Feb 12 20:26:20 2012
+++ /src/pkg/runtime/runtime.h Mon Feb 13 10:52:37 2012
@@ -267,11 +267,10 @@
};
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 @@
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);
=======================================
--- /src/pkg/runtime/signal_darwin_386.c Wed Dec 21 04:23:03 2011
+++ /src/pkg/runtime/signal_darwin_386.c Mon Feb 13 10:52:37 2012
@@ -24,14 +24,6 @@
runtime·printf("fs %x\n", r->fs);
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 @@
Regs32 *r;
uintptr *sp;
byte *pc;
+ SigTab *t;

uc = context;
mc = uc->uc_mcontext;
@@ -51,7 +44,10 @@
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 @@
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;
@@ -114,11 +113,6 @@

runtime·exit(2);
}
-
-void
-runtime·sigignore(int32, Siginfo*, void*)
-{
-}

void
runtime·signalstack(byte *p, int32 n)
@@ -131,8 +125,8 @@
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 @@
*(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();
-}
=======================================
--- /src/pkg/runtime/signal_darwin_amd64.c Mon Dec 19 12:51:13 2011
+++ /src/pkg/runtime/signal_darwin_amd64.c Mon Feb 13 10:52:37 2012
@@ -32,14 +32,6 @@
runtime·printf("fs %X\n", r->fs);
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 @@
Regs64 *r;
uintptr *sp;
byte *pc;
+ SigTab *t;

uc = context;
mc = uc->uc_mcontext;
@@ -59,7 +52,10 @@
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 @@
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;
@@ -124,11 +123,6 @@

runtime·exit(2);
}
-
-void
-runtime·sigignore(int32, Siginfo*, void*)
-{
-}

void
runtime·signalstack(byte *p, int32 n)
@@ -141,8 +135,8 @@
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 @@
*(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();
-}
=======================================
--- /src/pkg/runtime/signal_freebsd_386.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_freebsd_386.c Mon Feb 13 10:52:37 2012
@@ -50,6 +50,7 @@
Ucontext *uc;
Mcontext *r;
uintptr *sp;
+ SigTab *t;

uc = context;
r = &uc->uc_mcontext;
@@ -59,7 +60,10 @@
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 @@
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·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·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 @@
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();
-}
=======================================
--- /src/pkg/runtime/signal_freebsd_amd64.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_freebsd_amd64.c Mon Feb 13 10:52:37 2012
@@ -43,14 +43,6 @@
runtime·printf("fs %X\n", r->mc_fs);
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 @@
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 @@
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·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·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 @@
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();
-}
=======================================
--- /src/pkg/runtime/signal_linux_386.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_linux_386.c Mon Feb 13 10:52:37 2012
@@ -30,16 +30,7 @@
* 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)
@@ -47,6 +38,7 @@
Ucontext *uc;
Sigcontext *r;
uintptr *sp;
+ SigTab *t;

uc = context;
r = &uc->uc_mcontext;
@@ -56,7 +48,10 @@
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 @@
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·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;

@@ -135,60 +133,14 @@
sa.k_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();
-}

#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 @@
runtime·_vdso = auxv[1];
break;
}
- }
-}
+ }
+}
=======================================
--- /src/pkg/runtime/signal_linux_amd64.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_linux_amd64.c Mon Feb 13 10:52:37 2012
@@ -38,16 +38,7 @@
* 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 @@
Mcontext *mc;
Sigcontext *r;
uintptr *sp;
+ SigTab *t;

uc = context;
mc = &uc->uc_mcontext;
@@ -66,7 +58,10 @@
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 @@
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·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 @@
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();
-}
=======================================
--- /src/pkg/runtime/signal_linux_arm.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_linux_arm.c Mon Feb 13 10:52:37 2012
@@ -38,16 +38,7 @@
* 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·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 @@
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();
-}
=======================================
--- /src/pkg/runtime/signal_netbsd_386.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_netbsd_386.c Mon Feb 13 10:52:37 2012
@@ -35,27 +35,23 @@
runtime·printf("fs %x\n", r->sc_fs);
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 @@
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·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·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 @@
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();
-}
=======================================
--- /src/pkg/runtime/signal_netbsd_amd64.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_netbsd_amd64.c Mon Feb 13 10:52:37 2012
@@ -43,20 +43,13 @@
runtime·printf("fs %X\n", r->sc_fs);
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 @@
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 @@
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·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·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 @@
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();
-}
=======================================
--- /src/pkg/runtime/signal_openbsd_386.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_openbsd_386.c Mon Feb 13 10:52:37 2012
@@ -35,27 +35,23 @@
runtime·printf("fs %x\n", r->sc_fs);
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 @@
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·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·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 @@
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();
-}
=======================================
--- /src/pkg/runtime/signal_openbsd_amd64.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_openbsd_amd64.c Mon Feb 13 10:52:37 2012
@@ -43,20 +43,13 @@
runtime·printf("fs %X\n", r->sc_fs);
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 @@
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 @@
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·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·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 @@
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();
-}
=======================================
--- /src/pkg/runtime/signal_windows_386.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_windows_386.c Mon Feb 13 10:52:37 2012
@@ -25,7 +25,7 @@
}

void
-runtime·initsig(int32)
+runtime·initsig(void)
{
runtime·siginit();
}
=======================================
--- /src/pkg/runtime/signal_windows_amd64.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signal_windows_amd64.c Mon Feb 13 10:52:37 2012
@@ -35,7 +35,7 @@
}

void
-runtime·initsig(int32)
+runtime·initsig(void)
{
runtime·siginit();
// following line keeps sigtramp alive at link stage
=======================================
--- /src/pkg/runtime/signals_darwin.h Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signals_darwin.h Mon Feb 13 10:52:37 2012
@@ -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
=======================================
--- /src/pkg/runtime/signals_freebsd.h Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signals_freebsd.h Mon Feb 13 10:52:37 2012
@@ -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
=======================================
--- /src/pkg/runtime/signals_linux.h Wed Dec 21 15:45:36 2011
+++ /src/pkg/runtime/signals_linux.h Mon Feb 13 10:52:37 2012
@@ -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
=======================================
--- /src/pkg/runtime/signals_netbsd.h Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signals_netbsd.h Mon Feb 13 10:52:37 2012
@@ -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
=======================================
--- /src/pkg/runtime/signals_openbsd.h Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/signals_openbsd.h Mon Feb 13 10:52:37 2012
@@ -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
=======================================
--- /src/pkg/runtime/sigqueue.goc Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/sigqueue.goc Mon Feb 13 10:52:37 2012
@@ -39,18 +39,15 @@
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
@@ -58,17 +55,17 @@
{
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 @@
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;
- }
-}
-
-func Signame(sig int32) (name String) {
- name = runtime·signame(sig);
+ // 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();
+ }
+
+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);
+}
=======================================
--- /src/pkg/runtime/sys_linux_386.s Mon Dec 19 12:51:13 2011
+++ /src/pkg/runtime/sys_linux_386.s Mon Feb 13 10:52:37 2012
@@ -175,9 +175,6 @@

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,
=======================================
--- /src/pkg/runtime/sys_linux_amd64.s Mon Dec 19 12:51:13 2011
+++ /src/pkg/runtime/sys_linux_amd64.s Mon Feb 13 10:52:37 2012
@@ -157,9 +157,6 @@
MOVQ R10, g(BX)
RET

-TEXT runtime·sigignore(SB),7,$0
- RET
-
TEXT runtime·sigreturn(SB),7,$0
MOVL $15, AX // rt_sigreturn
SYSCALL
=======================================
--- /src/pkg/runtime/sys_linux_arm.s Tue Jan 10 20:48:02 2012
+++ /src/pkg/runtime/sys_linux_arm.s Mon Feb 13 10:52:37 2012
@@ -271,9 +271,6 @@
SWI $0
RET

-TEXT runtime·sigignore(SB),7,$0
- RET
-
TEXT runtime·sigtramp(SB),7,$24
// save g
MOVW g, R3
=======================================
--- /src/pkg/runtime/thread_plan9.c Fri Dec 16 12:33:58 2011
+++ /src/pkg/runtime/thread_plan9.c Mon Feb 13 10:52:37 2012
@@ -48,7 +48,7 @@
}

void
-runtime·initsig(int32)
+runtime·initsig(void)
{
}

=======================================
--- /src/pkg/syscall/mkerrors.sh Thu Feb 2 19:22:40 2012
+++ /src/pkg/syscall/mkerrors.sh Mon Feb 13 10:52:37 2012
@@ -209,36 +209,55 @@
echo ')'
) >_const.go

-# Pull out just the error names for later.
+# Pull out the error names for later.
errors=$(
echo '#include <errno.h>' | $GCC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print $2 }' |
sort
)

+# Pull out the signal names for later.
+signals=$(
+ echo '#include <signal.h>' | $GCC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print $2 }' |
+ egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+ sort
+)
+
# Again, writing regexps to a file.
echo '#include <errno.h>' | $GCC -x c - -E -dM $ccflags |
awk '$1=="#define" && $2 ~ /^E[A-Z0-9_]+$/ { print "^\t" $2 "[ \t]*=" }' |
sort >_error.grep
+echo '#include <signal.h>' | $GCC -x c - -E -dM $ccflags |
+ awk '$1=="#define" && $2 ~ /^SIG[A-Z0-9]+$/ { print "^\t" $2 "[ \t]*=" }'
|
+ egrep -v '(SIGSTKSIZE|SIGSTKSZ|SIGRT)' |
+ sort >_signal.grep

echo '// mkerrors.sh' "$@"
echo '// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT'
echo
go tool cgo -godefs -- "$@" _const.go >_error.out
-cat _error.out | grep -vf _error.grep
+cat _error.out | grep -vf _error.grep | grep -vf _signal.grep
echo
echo '// Errors'
echo 'const ('
cat _error.out | grep -f _error.grep | sed 's/=\(.*\)/= Errno(\1)/'
echo ')'

-# Run C program to print error strings.
+echo
+echo '// Signals'
+echo 'const ('
+cat _error.out | grep -f _signal.grep | sed 's/=\(.*\)/= Signal(\1)/'
+echo ')'
+
+# Run C program to print error and syscall strings.
(
/bin/echo "
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
+#include <signal.h>

#define nelem(x) (sizeof(x)/sizeof((x)[0]))

@@ -251,6 +270,16 @@
/bin/echo ' '$i,
done

+ /bin/echo "
+};
+
+int signals[] = {
+"
+ for i in $signals
+ do
+ /bin/echo ' '$i,
+ done
+
# Use /bin/echo to avoid builtin echo,
# which interprets \n itself
/bin/echo '
@@ -266,7 +295,7 @@
main(void)
{
int i, j, e;
- char buf[1024];
+ char buf[1024], *p;

printf("\n\n// Error table\n");
printf("var errors = [...]string {\n");
@@ -282,10 +311,30 @@
printf("\t%d: \"%s\",\n", e, buf);
}
printf("}\n\n");
+
+ printf("\n\n// Signal table\n");
+ printf("var signals = [...]string {\n");
+ qsort(signals, nelem(signals), sizeof signals[0], intcmp);
+ for(i=0; i<nelem(signals); i++) {
+ e = signals[i];
+ if(i > 0 && signals[i-1] == e)
+ continue;
+ strcpy(buf, strsignal(e));
+ // lowercase first letter: Bad -> bad, but STREAM -> STREAM.
+ if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
+ buf[0] += a - A;
+ // cut trailing : number.
+ p = strrchr(buf, ":"[0]);
+ if(p)
+ *p = '\0';
+ printf("\t%d: \"%s\",\n", e, buf);
+ }
+ printf("}\n\n");
+
return 0;
}

'
) >_errors.c

-$GCC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c
_errors _const.go _error.grep _error.out
+$GCC $ccflags -o _errors _errors.c && $GORUN ./_errors && rm -f _errors.c
_errors _const.go _error.grep _signal.grep _error.out
=======================================
--- /src/pkg/syscall/syscall_bsd.go Fri Jan 13 13:40:55 2012
+++ /src/pkg/syscall/syscall_bsd.go Mon Feb 13 10:52:37 2012
@@ -106,8 +106,8 @@

func (w WaitStatus) Signaled() bool { return w&mask != stopped &&
w&mask != 0 }

-func (w WaitStatus) Signal() int {
- sig := int(w & mask)
+func (w WaitStatus) Signal() Signal {
+ sig := Signal(w & mask)
if sig == stopped || sig == 0 {
return -1
}
@@ -116,15 +116,15 @@

func (w WaitStatus) CoreDump() bool { return w.Signaled() && w&core != 0 }

-func (w WaitStatus) Stopped() bool { return w&mask == stopped &&
w>>shift != SIGSTOP }
-
-func (w WaitStatus) Continued() bool { return w&mask == stopped &&
w>>shift == SIGSTOP }
-
-func (w WaitStatus) StopSignal() int {
+func (w WaitStatus) Stopped() bool { return w&mask == stopped &&
Signal(w>>shift) != SIGSTOP }
+
+func (w WaitStatus) Continued() bool { return w&mask == stopped &&
Signal(w>>shift) == SIGSTOP }
+
+func (w WaitStatus) StopSignal() Signal {
if !w.Stopped() {
return -1
}
- return int(w>>shift) & 0xFF
+ return Signal(w>>shift) & 0xFF
}

func (w WaitStatus) TrapCause() int { return -1 }
=======================================
--- /src/pkg/syscall/syscall_darwin.go Fri Jan 13 13:40:55 2012
+++ /src/pkg/syscall/syscall_darwin.go Mon Feb 13 10:52:37 2012
@@ -104,7 +104,7 @@

//sys kill(pid int, signum int, posix int) (err error)

-func Kill(pid int, signum int) (err error) { return kill(pid, signum, 1) }
+func Kill(pid int, signum Signal) (err error) { return kill(pid,
int(signum), 1) }

/*
* Exposed directly
=======================================
--- /src/pkg/syscall/syscall_linux.go Sun Feb 12 21:11:36 2012
+++ /src/pkg/syscall/syscall_linux.go Mon Feb 13 10:52:37 2012
@@ -151,18 +151,18 @@
return int(w>>shift) & 0xFF
}

-func (w WaitStatus) Signal() int {
+func (w WaitStatus) Signal() Signal {
if !w.Signaled() {
return -1
}
- return int(w & mask)
+ return Signal(w & mask)
}

-func (w WaitStatus) StopSignal() int {
+func (w WaitStatus) StopSignal() Signal {
if !w.Stopped() {
return -1
}
- return int(w>>shift) & 0xFF
+ return Signal(w>>shift) & 0xFF
}

func (w WaitStatus) TrapCause() int {
@@ -830,7 +830,7 @@
//sysnb InotifyInit() (fd int, err error)
//sysnb InotifyInit1(flags int) (fd int, err error)
//sysnb InotifyRmWatch(fd int, watchdesc uint32) (success int, err error)
-//sysnb Kill(pid int, sig int) (err error)
+//sysnb Kill(pid int, sig Signal) (err error)
//sys Klogctl(typ int, buf []byte) (n int, err error) = SYS_SYSLOG
//sys Link(oldpath string, newpath string) (err error)
//sys Mkdir(path string, mode uint32) (err error)
=======================================
--- /src/pkg/syscall/syscall_unix.go Fri Jan 13 13:40:55 2012
+++ /src/pkg/syscall/syscall_unix.go Mon Feb 13 10:52:37 2012
@@ -111,3 +111,19 @@
func (e Errno) Timeout() bool {
return e == EAGAIN || e == EWOULDBLOCK || e == ETIMEDOUT
}
+
+// A Signal is a number describing a process signal.
+// It implements the os.Signal interface.
+type Signal int
+
+func (s Signal) Signal() {}
+
+func (s Signal) String() string {
+ if 0 <= s && int(s) < len(signals) {
+ str := signals[s]
+ if str != "" {
+ return str
+ }
+ }
+ return "signal " + itoa(int(s))
+}
=======================================
***Additional files exist in this changeset.***
Reply all
Reply to author
Forward
0 new messages