mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			221 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			221 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Go
		
	
	
	
// Copyright 2015 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.
 | 
						|
 | 
						|
Signals are primarily used on Unix-like systems. For the use of this
 | 
						|
package on Windows and Plan 9, see below.
 | 
						|
 | 
						|
Types of signals
 | 
						|
 | 
						|
The signals SIGKILL and SIGSTOP may not be caught by a program, and
 | 
						|
therefore cannot be affected by this package.
 | 
						|
 | 
						|
Synchronous signals are signals triggered by errors in program
 | 
						|
execution: SIGBUS, SIGFPE, and SIGSEGV. These are only considered
 | 
						|
synchronous when caused by program execution, not when sent using
 | 
						|
os.Process.Kill or the kill program or some similar mechanism. In
 | 
						|
general, except as discussed below, Go programs will convert a
 | 
						|
synchronous signal into a run-time panic.
 | 
						|
 | 
						|
The remaining signals are asynchronous signals. They are not
 | 
						|
triggered by program errors, but are instead sent from the kernel or
 | 
						|
from some other program.
 | 
						|
 | 
						|
Of the asynchronous signals, the SIGHUP signal is sent when a program
 | 
						|
loses its controlling terminal. The SIGINT signal is sent when the
 | 
						|
user at the controlling terminal presses the interrupt character,
 | 
						|
which by default is ^C (Control-C). The SIGQUIT signal is sent when
 | 
						|
the user at the controlling terminal presses the quit character, which
 | 
						|
by default is ^\ (Control-Backslash). In general you can cause a
 | 
						|
program to simply exit by pressing ^C, and you can cause it to exit
 | 
						|
with a stack dump by pressing ^\.
 | 
						|
 | 
						|
Default behavior of signals in Go programs
 | 
						|
 | 
						|
By default, a synchronous signal is converted into a run-time panic. A
 | 
						|
SIGHUP, SIGINT, or SIGTERM signal causes the program to exit. A
 | 
						|
SIGQUIT, SIGILL, SIGTRAP, SIGABRT, SIGSTKFLT, SIGEMT, or SIGSYS signal
 | 
						|
causes the program to exit with a stack dump. A SIGTSTP, SIGTTIN, or
 | 
						|
SIGTTOU signal gets the system default behavior (these signals are
 | 
						|
used by the shell for job control). The SIGPROF signal is handled
 | 
						|
directly by the Go runtime to implement runtime.CPUProfile. Other
 | 
						|
signals will be caught but no action will be taken.
 | 
						|
 | 
						|
If the Go program is started with either SIGHUP or SIGINT ignored
 | 
						|
(signal handler set to SIG_IGN), they will remain ignored.
 | 
						|
 | 
						|
If the Go program is started with a non-empty signal mask, that will
 | 
						|
generally be honored. However, some signals are explicitly unblocked:
 | 
						|
the synchronous signals, SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF,
 | 
						|
and, on GNU/Linux, signals 32 (SIGCANCEL) and 33 (SIGSETXID)
 | 
						|
(SIGCANCEL and SIGSETXID are used internally by glibc). Subprocesses
 | 
						|
started by os.Exec, or by the os/exec package, will inherit the
 | 
						|
modified signal mask.
 | 
						|
 | 
						|
Changing the behavior of signals in Go programs
 | 
						|
 | 
						|
The functions in this package allow a program to change the way Go
 | 
						|
programs handle signals.
 | 
						|
 | 
						|
Notify disables the default behavior for a given set of asynchronous
 | 
						|
signals and instead delivers them over one or more registered
 | 
						|
channels. Specifically, it applies to the signals SIGHUP, SIGINT,
 | 
						|
SIGQUIT, SIGABRT, and SIGTERM. It also applies to the job control
 | 
						|
signals SIGTSTP, SIGTTIN, and SIGTTOU, in which case the system
 | 
						|
default behavior does not occur. It also applies to some signals that
 | 
						|
otherwise cause no action: SIGUSR1, SIGUSR2, SIGPIPE, SIGALRM,
 | 
						|
SIGCHLD, SIGCONT, SIGURG, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGWINCH,
 | 
						|
SIGIO, SIGPWR, SIGSYS, SIGINFO, SIGTHR, SIGWAITING, SIGLWP, SIGFREEZE,
 | 
						|
SIGTHAW, SIGLOST, SIGXRES, SIGJVM1, SIGJVM2, and any real time signals
 | 
						|
used on the system. Note that not all of these signals are available
 | 
						|
on all systems.
 | 
						|
 | 
						|
If the program was started with SIGHUP or SIGINT ignored, and Notify
 | 
						|
is called for either signal, a signal handler will be installed for
 | 
						|
that signal and it will no longer be ignored. If, later, Reset or
 | 
						|
Ignore is called for that signal, or Stop is called on all channels
 | 
						|
passed to Notify for that signal, the signal will once again be
 | 
						|
ignored. Reset will restore the system default behavior for the
 | 
						|
signal, while Ignore will cause the system to ignore the signal
 | 
						|
entirely.
 | 
						|
 | 
						|
If the program is started with a non-empty signal mask, some signals
 | 
						|
will be explicitly unblocked as described above. If Notify is called
 | 
						|
for a blocked signal, it will be unblocked. If, later, Reset is
 | 
						|
called for that signal, or Stop is called on all channels passed to
 | 
						|
Notify for that signal, the signal will once again be blocked.
 | 
						|
 | 
						|
SIGPIPE
 | 
						|
 | 
						|
When a Go program writes to a broken pipe, the kernel will raise a
 | 
						|
SIGPIPE signal.
 | 
						|
 | 
						|
If the program has not called Notify to receive SIGPIPE signals, then
 | 
						|
the behavior depends on the file descriptor number. A write to a
 | 
						|
broken pipe on file descriptors 1 or 2 (standard output or standard
 | 
						|
error) will cause the program to exit with a SIGPIPE signal. A write
 | 
						|
to a broken pipe on some other file descriptor will take no action on
 | 
						|
the SIGPIPE signal, and the write will fail with an EPIPE error.
 | 
						|
 | 
						|
If the program has called Notify to receive SIGPIPE signals, the file
 | 
						|
descriptor number does not matter. The SIGPIPE signal will be
 | 
						|
delivered to the Notify channel, and the write will fail with an EPIPE
 | 
						|
error.
 | 
						|
 | 
						|
This means that, by default, command line programs will behave like
 | 
						|
typical Unix command line programs, while other programs will not
 | 
						|
crash with SIGPIPE when writing to a closed network connection.
 | 
						|
 | 
						|
Go programs that use cgo or SWIG
 | 
						|
 | 
						|
In a Go program that includes non-Go code, typically C/C++ code
 | 
						|
accessed using cgo or SWIG, Go's startup code normally runs first. It
 | 
						|
configures the signal handlers as expected by the Go runtime, before
 | 
						|
the non-Go startup code runs. If the non-Go startup code wishes to
 | 
						|
install its own signal handlers, it must take certain steps to keep Go
 | 
						|
working well. This section documents those steps and the overall
 | 
						|
effect changes to signal handler settings by the non-Go code can have
 | 
						|
on Go programs. In rare cases, the non-Go code may run before the Go
 | 
						|
code, in which case the next section also applies.
 | 
						|
 | 
						|
If the non-Go code called by the Go program does not change any signal
 | 
						|
handlers or masks, then the behavior is the same as for a pure Go
 | 
						|
program.
 | 
						|
 | 
						|
If the non-Go code installs any signal handlers, it must use the
 | 
						|
SA_ONSTACK flag with sigaction. Failing to do so is likely to cause
 | 
						|
the program to crash if the signal is received. Go programs routinely
 | 
						|
run with a limited stack, and therefore set up an alternate signal
 | 
						|
stack. Also, the Go standard library expects that any signal handlers
 | 
						|
will use the SA_RESTART flag. Failing to do so may cause some library
 | 
						|
calls to return "interrupted system call" errors.
 | 
						|
 | 
						|
If the non-Go code installs a signal handler for any of the
 | 
						|
synchronous signals (SIGBUS, SIGFPE, SIGSEGV), then it should record
 | 
						|
the existing Go signal handler. If those signals occur while
 | 
						|
executing Go code, it should invoke the Go signal handler (whether the
 | 
						|
signal occurs while executing Go code can be determined by looking at
 | 
						|
the PC passed to the signal handler). Otherwise some Go run-time
 | 
						|
panics will not occur as expected.
 | 
						|
 | 
						|
If the non-Go code installs a signal handler for any of the
 | 
						|
asynchronous signals, it may invoke the Go signal handler or not as it
 | 
						|
chooses. Naturally, if it does not invoke the Go signal handler, the
 | 
						|
Go behavior described above will not occur. This can be an issue with
 | 
						|
the SIGPROF signal in particular.
 | 
						|
 | 
						|
The non-Go code should not change the signal mask on any threads
 | 
						|
created by the Go runtime. If the non-Go code starts new threads of
 | 
						|
its own, it may set the signal mask as it pleases.
 | 
						|
 | 
						|
If the non-Go code starts a new thread, changes the signal mask, and
 | 
						|
then invokes a Go function in that thread, the Go runtime will
 | 
						|
automatically unblock certain signals: the synchronous signals,
 | 
						|
SIGILL, SIGTRAP, SIGSTKFLT, SIGCHLD, SIGPROF, SIGCANCEL, and
 | 
						|
SIGSETXID. When the Go function returns, the non-Go signal mask will
 | 
						|
be restored.
 | 
						|
 | 
						|
If the Go signal handler is invoked on a non-Go thread not running Go
 | 
						|
code, the handler generally forwards the signal to the non-Go code, as
 | 
						|
follows. If the signal is SIGPROF, the Go handler does
 | 
						|
nothing. Otherwise, the Go handler removes itself, unblocks the
 | 
						|
signal, and raises it again, to invoke any non-Go handler or default
 | 
						|
system handler. If the program does not exit, the Go handler then
 | 
						|
reinstalls itself and continues execution of the program.
 | 
						|
 | 
						|
Non-Go programs that call Go code
 | 
						|
 | 
						|
When Go code is built with options like -buildmode=c-shared, it will
 | 
						|
be run as part of an existing non-Go program. The non-Go code may
 | 
						|
have already installed signal handlers when the Go code starts (that
 | 
						|
may also happen in unusual cases when using cgo or SWIG; in that case,
 | 
						|
the discussion here applies).  For -buildmode=c-archive the Go runtime
 | 
						|
will initialize signals at global constructor time.  For
 | 
						|
-buildmode=c-shared the Go runtime will initialize signals when the
 | 
						|
shared library is loaded.
 | 
						|
 | 
						|
If the Go runtime sees an existing signal handler for the SIGCANCEL or
 | 
						|
SIGSETXID signals (which are used only on GNU/Linux), it will turn on
 | 
						|
the SA_ONSTACK flag and otherwise keep the signal handler.
 | 
						|
 | 
						|
For the synchronous signals, the Go runtime will install a signal
 | 
						|
handler. It will save any existing signal handler. If a synchronous
 | 
						|
signal arrives while executing non-Go code, the Go runtime will invoke
 | 
						|
the existing signal handler instead of the Go signal handler.
 | 
						|
 | 
						|
Go code built with -buildmode=c-archive or -buildmode=c-shared will
 | 
						|
not install any other signal handlers by default. If there is an
 | 
						|
existing signal handler, the Go runtime will turn on the SA_ONSTACK
 | 
						|
flag and otherwise keep the signal handler. If Notify is called for an
 | 
						|
asynchronous signal, a Go signal handler will be installed for that
 | 
						|
signal. If, later, Reset is called for that signal, the original
 | 
						|
handling for that signal will be reinstalled, restoring the non-Go
 | 
						|
signal handler if any.
 | 
						|
 | 
						|
Go code built without -buildmode=c-archive or -buildmode=c-shared will
 | 
						|
install a signal handler for the asynchronous signals listed above,
 | 
						|
and save any existing signal handler. If a signal is delivered to a
 | 
						|
non-Go thread, it will act as described above, except that if there is
 | 
						|
an existing non-Go signal handler, that handler will be installed
 | 
						|
before raising the signal.
 | 
						|
 | 
						|
Windows
 | 
						|
 | 
						|
On Windows a ^C (Control-C) or ^BREAK (Control-Break) normally cause
 | 
						|
the program to exit. If Notify is called for os.Interrupt, ^C or ^BREAK
 | 
						|
will cause os.Interrupt to be sent on the channel, and the program will
 | 
						|
not exit. If Reset is called, or Stop is called on all channels passed
 | 
						|
to Notify, then the default behavior will be restored.
 | 
						|
 | 
						|
Plan 9
 | 
						|
 | 
						|
On Plan 9, signals have type syscall.Note, which is a string. Calling
 | 
						|
Notify with a syscall.Note will cause that value to be sent on the
 | 
						|
channel when that string is posted as a note.
 | 
						|
 | 
						|
*/
 | 
						|
package signal
 |