1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Test os/signal.Notify and os/signal.Reset.
6 // This is a lot like ../testcshared/main5.c.
19 static void die(const char* msg) {
24 static volatile sig_atomic_t sigioSeen;
26 static void ioHandler(int signo, siginfo_t* info, void* ctxt) {
30 // Set up the SIGPIPE signal handler in a high priority constructor, so
31 // that it is installed before the Go code starts.
33 static void pipeHandler(int signo, siginfo_t* info, void* ctxt) {
34 const char *s = "unexpected SIGPIPE\n";
35 write(2, s, strlen(s));
39 static void init(void) __attribute__ ((constructor (200)));
44 memset(&sa, 0, sizeof sa);
45 sa.sa_sigaction = pipeHandler;
46 if (sigemptyset(&sa.sa_mask) < 0) {
49 sa.sa_flags = SA_SIGINFO;
50 if (sigaction(SIGPIPE, &sa, NULL) < 0) {
55 static void *provokeSIGPIPE(void *arg) {
60 int main(int argc, char** argv) {
69 setvbuf(stdout, NULL, _IONBF, 0);
72 printf("raising SIGPIPE\n");
75 // Test that the Go runtime handles SIGPIPE, even if we installed
76 // a non-default SIGPIPE handler before the runtime initializes.
79 // Test that SIGPIPE on a non-main thread is also handled by Go.
80 res = pthread_create(&tid, NULL, provokeSIGPIPE, NULL);
82 fprintf(stderr, "pthread_create: %s\n", strerror(res));
86 res = pthread_join(tid, NULL);
88 fprintf(stderr, "pthread_join: %s\n", strerror(res));
93 printf("calling sigaction\n");
96 memset(&sa, 0, sizeof sa);
97 sa.sa_sigaction = ioHandler;
98 if (sigemptyset(&sa.sa_mask) < 0) {
101 sa.sa_flags = SA_SIGINFO;
102 if (sigaction(SIGIO, &sa, NULL) < 0) {
106 // At this point there should not be a Go signal handler
107 // installed for SIGIO.
110 printf("raising SIGIO\n");
113 if (raise(SIGIO) < 0) {
118 printf("waiting for sigioSeen\n");
121 // Wait until the signal has been delivered.
125 ts.tv_nsec = 1000000;
126 nanosleep(&ts, NULL);
129 fprintf(stderr, "looping too long waiting for signal\n");
136 // Tell the Go code to catch SIGIO.
139 printf("calling CatchSIGIO\n");
145 printf("raising SIGIO\n");
148 if (raise(SIGIO) < 0) {
153 printf("calling SawSIGIO\n");
157 fprintf(stderr, "Go handler did not see SIGIO\n");
161 if (sigioSeen != 0) {
162 fprintf(stderr, "C handler saw SIGIO when only Go handler should have\n");
166 // Tell the Go code to stop catching SIGIO.
169 printf("calling ResetSIGIO\n");
175 printf("raising SIGIO\n");
178 if (raise(SIGIO) < 0) {
183 printf("calling SawSIGIO\n");
187 fprintf(stderr, "Go handler saw SIGIO after Reset\n");
192 printf("waiting for sigioSeen\n");
195 // Wait until the signal has been delivered.
199 ts.tv_nsec = 1000000;
200 nanosleep(&ts, NULL);
203 fprintf(stderr, "looping too long waiting for signal\n");