mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: handle SIGPIPE in c-archive and c-shared programs
Before this CL, Go programs in c-archive or c-shared buildmodes would not handle SIGPIPE. That leads to surprising behaviour where writes on a closed pipe or socket would raise SIGPIPE and terminate the program. This CL changes the Go runtime to handle SIGPIPE regardless of buildmode. In addition, SIGPIPE from non-Go code is forwarded. Fixes #17393 Updates #16760 Change-Id: I155e82020a03a5cdc627a147c27da395662c3fe8 Reviewed-on: https://go-review.googlesource.com/32796 Run-TryBot: Elias Naur <elias.naur@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
e54662dc85
commit
d24b57a6a1
8 changed files with 136 additions and 9 deletions
|
|
@ -111,8 +111,8 @@ func sigInstallGoHandler(sig uint32) bool {
|
|||
}
|
||||
|
||||
// When built using c-archive or c-shared, only install signal
|
||||
// handlers for synchronous signals.
|
||||
if (isarchive || islibrary) && t.flags&_SigPanic == 0 {
|
||||
// handlers for synchronous signals and SIGPIPE.
|
||||
if (isarchive || islibrary) && t.flags&_SigPanic == 0 && sig != _SIGPIPE {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -492,9 +492,15 @@ func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// Only forward synchronous signals.
|
||||
c := &sigctxt{info, ctx}
|
||||
if c.sigcode() == _SI_USER || flags&_SigPanic == 0 {
|
||||
// Only forward signals from the kernel.
|
||||
// On Linux and Darwin there is no way to distinguish a SIGPIPE raised by a write
|
||||
// to a closed socket or pipe from a SIGPIPE raised by kill or pthread_kill
|
||||
// so we'll treat every SIGPIPE as kernel-generated.
|
||||
userSig := c.sigcode() == _SI_USER &&
|
||||
(sig != _SIGPIPE || GOOS != "linux" && GOOS != "android" && GOOS != "darwin")
|
||||
// Only forward synchronous signals and SIGPIPE.
|
||||
if userSig || flags&_SigPanic == 0 && sig != _SIGPIPE {
|
||||
return false
|
||||
}
|
||||
// Determine if the signal occurred inside Go code. We test that:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue