diff options
| author | Ian Lance Taylor <iant@golang.org> | 2015-12-19 10:17:10 -0800 |
|---|---|---|
| committer | Ian Lance Taylor <iant@golang.org> | 2016-01-06 23:14:46 +0000 |
| commit | 70c9a8187a2732f969aaaa78e0e6f139d04ef3eb (patch) | |
| tree | 697f0aaffd3f5c29089adb2416d4c22543a40196 /src/runtime/testdata/testprogcgo/exec.go | |
| parent | a7cad52e04dd1890420452b38563997930edb2ca (diff) | |
| download | go-70c9a8187a2732f969aaaa78e0e6f139d04ef3eb.tar.xz | |
runtime: set new m signal mask to program startup mask
We were setting the signal mask of a new m to the signal mask of the m
that created it. That failed when that m happened to be the one created
by ensureSigM, which sets its signal mask to only include the signals
being caught by os/signal.Notify.
Fixes #13164.
Update #9896.
Change-Id: I705c196fe9d11754e10bab9e9b2e7530ecdfa367
Reviewed-on: https://go-review.googlesource.com/18064
Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime/testdata/testprogcgo/exec.go')
| -rw-r--r-- | src/runtime/testdata/testprogcgo/exec.go | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/runtime/testdata/testprogcgo/exec.go b/src/runtime/testdata/testprogcgo/exec.go new file mode 100644 index 0000000000..8dc1d517c6 --- /dev/null +++ b/src/runtime/testdata/testprogcgo/exec.go @@ -0,0 +1,89 @@ +// 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. + +// +build !plan9,!windows + +package main + +/* +#include <stddef.h> +#include <signal.h> +#include <pthread.h> + +// Save the signal mask at startup so that we see what it is before +// the Go runtime starts setting up signals. + +static sigset_t mask; + +static void init(void) __attribute__ ((constructor)); + +static void init() { + sigemptyset(&mask); + pthread_sigmask(SIG_SETMASK, NULL, &mask); +} + +int SIGINTBlocked() { + return sigismember(&mask, SIGINT); +} +*/ +import "C" + +import ( + "fmt" + "os" + "os/exec" + "os/signal" + "sync" + "syscall" +) + +func init() { + register("CgoExecSignalMask", CgoExecSignalMask) +} + +func CgoExecSignalMask() { + if len(os.Args) > 2 && os.Args[2] == "testsigint" { + if C.SIGINTBlocked() != 0 { + os.Exit(1) + } + os.Exit(0) + } + + c := make(chan os.Signal, 1) + signal.Notify(c, syscall.SIGTERM) + go func() { + for range c { + } + }() + + const goCount = 10 + const execCount = 10 + var wg sync.WaitGroup + wg.Add(goCount*execCount + goCount) + for i := 0; i < goCount; i++ { + go func() { + defer wg.Done() + for j := 0; j < execCount; j++ { + c2 := make(chan os.Signal, 1) + signal.Notify(c2, syscall.SIGUSR1) + syscall.Kill(os.Getpid(), syscall.SIGTERM) + go func(j int) { + defer wg.Done() + cmd := exec.Command(os.Args[0], "CgoExecSignalMask", "testsigint") + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + fmt.Printf("iteration %d: %v\n", j, err) + os.Exit(1) + } + }(j) + signal.Stop(c2) + } + }() + } + wg.Wait() + + fmt.Println("OK") +} |
