runtime: if os/signal is not in use, crash on
	most signals, so that ordinary programs
	can be killed, for example.

Fixes #434.

R=dsymonds1
CC=golang-dev, hoisie
https://golang.org/cl/180064
diff --git a/src/pkg/runtime/darwin/386/signal.c b/src/pkg/runtime/darwin/386/signal.c
index 4023439..7978739 100644
--- a/src/pkg/runtime/darwin/386/signal.c
+++ b/src/pkg/runtime/darwin/386/signal.c
@@ -41,8 +41,9 @@
 	Regs *r;
 
 	if(sigtab[sig].flags & SigQueue) {
-		sigsend(sig);
-		return;
+		if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
+			return;
+		exit(2);	// SIGINT, SIGTERM, etc
 	}
 
 	if(panicking)	// traceback already printed
diff --git a/src/pkg/runtime/darwin/amd64/signal.c b/src/pkg/runtime/darwin/amd64/signal.c
index 5e26a71..bf1bca9 100644
--- a/src/pkg/runtime/darwin/amd64/signal.c
+++ b/src/pkg/runtime/darwin/amd64/signal.c
@@ -49,8 +49,9 @@
 	Regs *r;
 
 	if(sigtab[sig].flags & SigQueue) {
-		sigsend(sig);
-		return;
+		if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
+			return;
+		exit(2);	// SIGINT, SIGTERM, etc
 	}
 
 	if(panicking)	// traceback already printed
diff --git a/src/pkg/runtime/darwin/signals.h b/src/pkg/runtime/darwin/signals.h
index 48a5db1..449a6a7 100644
--- a/src/pkg/runtime/darwin/signals.h
+++ b/src/pkg/runtime/darwin/signals.h
@@ -22,24 +22,24 @@
 	/* 11 */	C, "SIGSEGV: segmentation violation",
 	/* 12 */	C, "SIGSYS: bad system call",
 	/* 13 */	I, "SIGPIPE: write to broken pipe",
-	/* 14 */	Q+R, "SIGALRM: alarm clock",
+	/* 14 */	Q+I+R, "SIGALRM: alarm clock",
 	/* 15 */	Q+R, "SIGTERM: termination",
-	/* 16 */	Q+R, "SIGURG: urgent condition on socket",
+	/* 16 */	Q+I+R, "SIGURG: urgent condition on socket",
 	/* 17 */	0, "SIGSTOP: stop",
-	/* 18 */	Q+R, "SIGTSTP: keyboard stop",
+	/* 18 */	Q+I+R, "SIGTSTP: keyboard stop",
 	/* 19 */	0, "SIGCONT: continue after stop",
 	/* 20 */	I+R, "SIGCHLD: child status has changed",
-	/* 21 */	Q+R, "SIGTTIN: background read from tty",
-	/* 22 */	Q+R, "SIGTTOU: background write to tty",
-	/* 23 */	Q+R, "SIGIO: i/o now possible",
-	/* 24 */	Q+R, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	Q+R, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	Q+R, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	Q+R, "SIGPROF: profiling alarm clock",
-	/* 28 */	Q+R, "SIGWINCH: window size change",
-	/* 29 */	Q+R, "SIGINFO: status request from keyboard",
-	/* 30 */	Q+R, "SIGUSR1: user-defined signal 1",
-	/* 31 */	Q+R, "SIGUSR2: user-defined signal 2",
+	/* 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",
 };
 #undef C
 #undef I
diff --git a/src/pkg/runtime/extern.go b/src/pkg/runtime/extern.go
index 27cb73c..85b1659 100644
--- a/src/pkg/runtime/extern.go
+++ b/src/pkg/runtime/extern.go
@@ -66,3 +66,7 @@
 
 // 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/freebsd/386/signal.c b/src/pkg/runtime/freebsd/386/signal.c
index 7bad780..d687767 100644
--- a/src/pkg/runtime/freebsd/386/signal.c
+++ b/src/pkg/runtime/freebsd/386/signal.c
@@ -51,8 +51,9 @@
 	Mcontext *mc;
 
 	if(sigtab[sig].flags & SigQueue) {
-		sigsend(sig);
-		return;
+		if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
+			return;
+		exit(2);	// SIGINT, SIGTERM, etc
 	}
 
 	if(panicking)	// traceback already printed
diff --git a/src/pkg/runtime/freebsd/amd64/signal.c b/src/pkg/runtime/freebsd/amd64/signal.c
index ed03db1..d59259b 100644
--- a/src/pkg/runtime/freebsd/amd64/signal.c
+++ b/src/pkg/runtime/freebsd/amd64/signal.c
@@ -59,8 +59,9 @@
 	Mcontext *mc;
 
 	if(sigtab[sig].flags & SigQueue) {
-		sigsend(sig);
-		return;
+		if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
+			return;
+		exit(2);	// SIGINT, SIGTERM, etc
 	}
 
 	if(panicking)	// traceback already printed
diff --git a/src/pkg/runtime/freebsd/signals.h b/src/pkg/runtime/freebsd/signals.h
index 91ddef8..b986bcb 100644
--- a/src/pkg/runtime/freebsd/signals.h
+++ b/src/pkg/runtime/freebsd/signals.h
@@ -22,25 +22,25 @@
 	/* 11 */	C, "SIGSEGV: segmentation violation",
 	/* 12 */	C, "SIGSYS: bad system call",
 	/* 13 */	I, "SIGPIPE: write to broken pipe",
-	/* 14 */	Q+R, "SIGALRM: alarm clock",
+	/* 14 */	Q+I+R, "SIGALRM: alarm clock",
 	/* 15 */	Q+R, "SIGTERM: termination",
-	/* 16 */	Q+R, "SIGURG: urgent condition on socket",
+	/* 16 */	Q+I+R, "SIGURG: urgent condition on socket",
 	/* 17 */	0, "SIGSTOP: stop, unblockable",
-	/* 18 */	Q+R, "SIGTSTP: stop from tty",
+	/* 18 */	Q+I+R, "SIGTSTP: stop from tty",
 	/* 19 */	0, "SIGCONT: continue",
 	/* 20 */	I+R, "SIGCHLD: child status has changed",
-	/* 21 */	Q+R, "SIGTTIN: background read from tty",
-	/* 22 */	Q+R, "SIGTTOU: background write to tty",
-	/* 23 */	Q+R, "SIGIO: i/o now possible",
-	/* 24 */	Q+R, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	Q+R, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	Q+R, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	Q+R, "SIGPROF: profiling alarm clock",
-	/* 28 */	I+R, "SIGWINCH: window size change",
-	/* 29 */	Q+R, "SIGINFO: information request",
-	/* 30 */	Q+R, "SIGUSR1: user-defined signal 1",
-	/* 31 */	Q+R, "SIGUSR2: user-defined signal 2",
-	/* 32 */	Q+R, "SIGTHR: reserved",
+	/* 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",
 };
 #undef C
 #undef I
diff --git a/src/pkg/runtime/linux/386/signal.c b/src/pkg/runtime/linux/386/signal.c
index 2e6c7a5..c540083 100644
--- a/src/pkg/runtime/linux/386/signal.c
+++ b/src/pkg/runtime/linux/386/signal.c
@@ -48,8 +48,9 @@
 	Sigcontext *sc;
 
 	if(sigtab[sig].flags & SigQueue) {
-		sigsend(sig);
-		return;
+		if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
+			return;
+		exit(2);	// SIGINT, SIGTERM, etc
 	}
 
 	if(panicking)	// traceback already printed
diff --git a/src/pkg/runtime/linux/amd64/signal.c b/src/pkg/runtime/linux/amd64/signal.c
index 693b8c7..dba6fb1 100644
--- a/src/pkg/runtime/linux/amd64/signal.c
+++ b/src/pkg/runtime/linux/amd64/signal.c
@@ -57,8 +57,9 @@
 	Sigcontext *sc;
 
 	if(sigtab[sig].flags & SigQueue) {
-		sigsend(sig);
-		return;
+		if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
+			return;
+		exit(2);	// SIGINT, SIGTERM, etc
 	}
 
 	if(panicking)	// traceback already printed
diff --git a/src/pkg/runtime/linux/signals.h b/src/pkg/runtime/linux/signals.h
index 883ac4e..3431cd2 100644
--- a/src/pkg/runtime/linux/signals.h
+++ b/src/pkg/runtime/linux/signals.h
@@ -18,27 +18,27 @@
 	/* 7 */	C, "SIGBUS: bus error",
 	/* 8 */	C, "SIGFPE: floating-point exception",
 	/* 9 */	0, "SIGKILL: kill",
-	/* 10 */	Q+R, "SIGUSR1: user-defined signal 1",
+	/* 10 */	Q+I+R, "SIGUSR1: user-defined signal 1",
 	/* 11 */	C, "SIGSEGV: segmentation violation",
-	/* 12 */	Q+R, "SIGUSR2: user-defined signal 2",
+	/* 12 */	Q+I+R, "SIGUSR2: user-defined signal 2",
 	/* 13 */	I, "SIGPIPE: write to broken pipe",
-	/* 14 */	Q+R, "SIGALRM: alarm clock",
+	/* 14 */	Q+I+R, "SIGALRM: alarm clock",
 	/* 15 */	Q+R, "SIGTERM: termination",
-	/* 16 */	Q+R, "SIGSTKFLT: stack fault",
-	/* 17 */	Q+R, "SIGCHLD: child status has changed",
+	/* 16 */	C, "SIGSTKFLT: stack fault",
+	/* 17 */	I+R, "SIGCHLD: child status has changed",
 	/* 18 */	0, "SIGCONT: continue",
 	/* 19 */	0, "SIGSTOP: stop, unblockable",
-	/* 20 */	Q+R, "SIGTSTP: keyboard stop",
-	/* 21 */	Q+R, "SIGTTIN: background read from tty",
-	/* 22 */	Q+R, "SIGTTOU: background write to tty",
-	/* 23 */	Q+R, "SIGURG: urgent condition on socket",
-	/* 24 */	Q+R, "SIGXCPU: cpu limit exceeded",
-	/* 25 */	Q+R, "SIGXFSZ: file size limit exceeded",
-	/* 26 */	Q+R, "SIGVTALRM: virtual alarm clock",
-	/* 27 */	Q+R, "SIGPROF: profiling alarm clock",
-	/* 28 */	Q+R, "SIGWINCH: window size change",
-	/* 29 */	Q+R, "SIGIO: i/o now possible",
-	/* 30 */	Q+R, "SIGPWR: power failure restart",
+	/* 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",
 };
 #undef C
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index 46df412..91130a0 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -374,10 +374,10 @@
 void	gosched(void);
 void	goexit(void);
 void	runcgo(void (*fn)(void*), void*);
-void	entersyscall(void);
-void	exitsyscall(void);
+void	runtime·entersyscall(void);
+void	runtime·exitsyscall(void);
 void	siginit(void);
-void	sigsend(int32 sig);
+bool	sigsend(int32 sig);
 
 #pragma	varargck	argpos	printf	1
 
diff --git a/src/pkg/runtime/sigqueue.cgo b/src/pkg/runtime/sigqueue.cgo
index 059d3ed..c3751c5d 100644
--- a/src/pkg/runtime/sigqueue.cgo
+++ b/src/pkg/runtime/sigqueue.cgo
@@ -43,6 +43,7 @@
 static struct {
 	Note;
 	uint32 mask;
+	bool inuse;
 } sig;
 
 void
@@ -52,24 +53,27 @@
 }
 
 // Called from sighandler to send a signal back out of the signal handling thread.
-void
+bool
 sigsend(int32 s)
 {
 	uint32 bit, mask;
 
+	if(!sig.inuse)
+		return false;
 	bit = 1 << s;
 	for(;;) {
 		mask = sig.mask;
 		if(mask & bit)
-			return;		// signal already in queue
+			break;		// signal already in queue
 		if(cas(&sig.mask, mask, mask|bit)) {
 			// Added to queue.
 			// Only send a wakeup for the first signal in each round.
 			if(mask == 0)
 				notewakeup(&sig);
-			return;
+			break;
 		}
 	}
+	return true;
 }
 
 // Called to receive a bitmask of queued signals.
@@ -88,3 +92,7 @@
 func Signame(sig int32) (name String) {
 	name = signame(sig);
 }
+
+func Siginit() {
+	sig.inuse = true;	// enable reception of signals; cannot disable
+}