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