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  }