]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgo/misc/cgo/testsigfwd/main.go
libgo: update to Go1.14beta1
[thirdparty/gcc.git] / libgo / misc / cgo / testsigfwd / main.go
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.
4
5 package main
6
7 import "fmt"
8
9 /*
10 #cgo CFLAGS: -pthread
11 #cgo LDFLAGS: -pthread
12
13 #include <signal.h>
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <string.h>
17 #include <pthread.h>
18
19 int *p;
20 static void sigsegv() {
21 *p = 1;
22 fprintf(stderr, "ERROR: C SIGSEGV not thrown on caught?.\n");
23 exit(2);
24 }
25
26 static void segvhandler(int signum) {
27 if (signum == SIGSEGV) {
28 fprintf(stdout, "ok\ttestsigfwd\n");
29 exit(0); // success
30 }
31 }
32
33 static volatile sig_atomic_t sigioSeen;
34
35 // Use up some stack space.
36 static void recur(int i, char *p) {
37 char a[1024];
38
39 *p = '\0';
40 if (i > 0) {
41 recur(i - 1, a);
42 }
43 }
44
45 static void iohandler(int signum) {
46 char a[1024];
47
48 recur(4, a);
49 sigioSeen = 1;
50 }
51
52 static void* sigioThread(void* arg __attribute__ ((unused))) {
53 raise(SIGIO);
54 return NULL;
55 }
56
57 static void sigioOnThread() {
58 pthread_t tid;
59 int i;
60
61 pthread_create(&tid, NULL, sigioThread, NULL);
62 pthread_join(tid, NULL);
63
64 // Wait until the signal has been delivered.
65 i = 0;
66 while (!sigioSeen) {
67 if (sched_yield() < 0) {
68 perror("sched_yield");
69 }
70 i++;
71 if (i > 10000) {
72 fprintf(stderr, "looping too long waiting for signal\n");
73 exit(EXIT_FAILURE);
74 }
75 }
76 }
77
78 static void __attribute__ ((constructor)) sigsetup(void) {
79 struct sigaction act;
80
81 memset(&act, 0, sizeof act);
82 act.sa_handler = segvhandler;
83 sigaction(SIGSEGV, &act, NULL);
84
85 act.sa_handler = iohandler;
86 sigaction(SIGIO, &act, NULL);
87 }
88 */
89 import "C"
90
91 var p *byte
92
93 func f() (ret bool) {
94 defer func() {
95 if recover() == nil {
96 fmt.Errorf("ERROR: couldn't raise SIGSEGV in Go.")
97 C.exit(2)
98 }
99 ret = true
100 }()
101 *p = 1
102 return false
103 }
104
105 func main() {
106 // Test that the signal originating in Go is handled (and recovered) by Go.
107 if !f() {
108 fmt.Errorf("couldn't recover from SIGSEGV in Go.")
109 C.exit(2)
110 }
111
112 // Test that the signal originating in C is handled by C.
113 C.sigsegv()
114 }