github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/misc/cgo/testcarchive/main3.c (about) 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 // Test os/signal.Notify and os/signal.Reset. 6 // This is a lot like misc/cgo/testcshared/main5.c. 7 8 #include <signal.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <sched.h> 13 14 #include "libgo3.h" 15 16 static void die(const char* msg) { 17 perror(msg); 18 exit(EXIT_FAILURE); 19 } 20 21 static volatile sig_atomic_t sigioSeen; 22 23 static void ioHandler(int signo, siginfo_t* info, void* ctxt) { 24 sigioSeen = 1; 25 } 26 27 int main(int argc, char** argv) { 28 int verbose; 29 struct sigaction sa; 30 int i; 31 32 verbose = argc > 2; 33 setvbuf(stdout, NULL, _IONBF, 0); 34 35 if (verbose) { 36 printf("calling sigaction\n"); 37 } 38 39 memset(&sa, 0, sizeof sa); 40 sa.sa_sigaction = ioHandler; 41 if (sigemptyset(&sa.sa_mask) < 0) { 42 die("sigemptyset"); 43 } 44 sa.sa_flags = SA_SIGINFO; 45 if (sigaction(SIGIO, &sa, NULL) < 0) { 46 die("sigaction"); 47 } 48 49 // At this point there should not be a Go signal handler 50 // installed for SIGIO. 51 52 if (verbose) { 53 printf("raising SIGIO\n"); 54 } 55 56 if (raise(SIGIO) < 0) { 57 die("raise"); 58 } 59 60 if (verbose) { 61 printf("waiting for sigioSeen\n"); 62 } 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 > 100000) { 72 fprintf(stderr, "looping too long waiting for signal\n"); 73 exit(EXIT_FAILURE); 74 } 75 } 76 77 sigioSeen = 0; 78 79 // Tell the Go code to catch SIGIO. 80 81 if (verbose) { 82 printf("calling CatchSIGIO\n"); 83 } 84 85 CatchSIGIO(); 86 87 if (verbose) { 88 printf("raising SIGIO\n"); 89 } 90 91 if (raise(SIGIO) < 0) { 92 die("raise"); 93 } 94 95 if (verbose) { 96 printf("calling SawSIGIO\n"); 97 } 98 99 if (!SawSIGIO()) { 100 fprintf(stderr, "Go handler did not see SIGIO\n"); 101 exit(EXIT_FAILURE); 102 } 103 104 if (sigioSeen != 0) { 105 fprintf(stderr, "C handler saw SIGIO when only Go handler should have\n"); 106 exit(EXIT_FAILURE); 107 } 108 109 // Tell the Go code to stop catching SIGIO. 110 111 if (verbose) { 112 printf("calling ResetSIGIO\n"); 113 } 114 115 ResetSIGIO(); 116 117 if (verbose) { 118 printf("raising SIGIO\n"); 119 } 120 121 if (raise(SIGIO) < 0) { 122 die("raise"); 123 } 124 125 if (verbose) { 126 printf("calling SawSIGIO\n"); 127 } 128 129 if (SawSIGIO()) { 130 fprintf(stderr, "Go handler saw SIGIO after Reset\n"); 131 exit(EXIT_FAILURE); 132 } 133 134 if (verbose) { 135 printf("waiting for sigioSeen\n"); 136 } 137 138 // Wait until the signal has been delivered. 139 i = 0; 140 while (!sigioSeen) { 141 if (sched_yield() < 0) { 142 perror("sched_yield"); 143 } 144 i++; 145 if (i > 100000) { 146 fprintf(stderr, "looping too long waiting for signal\n"); 147 exit(EXIT_FAILURE); 148 } 149 } 150 151 printf("PASS\n"); 152 return 0; 153 }