1 /* 2 * Copyright 2016, Cyril Bur, IBM Corp. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Sending one self a signal should always get delivered. 10 */ 11 12 #include <signal.h> 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <sys/types.h> 17 #include <sys/wait.h> 18 #include <unistd.h> 19 20 #include <altivec.h> 21 22 #include "utils.h" 23 24 #define MAX_ATTEMPT 500000 25 #define TIMEOUT 5 26 27 extern long signal_self(pid_t pid, int sig); 28 29 static sig_atomic_t signaled; 30 static sig_atomic_t fail; 31 32 static void signal_handler(int sig) 33 { 34 if (sig == SIGUSR1) 35 signaled = 1; 36 else 37 fail = 1; 38 } 39 40 static int test_signal() 41 { 42 int i; 43 struct sigaction act; 44 pid_t ppid = getpid(); 45 pid_t pid; 46 47 act.sa_handler = signal_handler; 48 act.sa_flags = 0; 49 sigemptyset(&act.sa_mask); 50 if (sigaction(SIGUSR1, &act, NULL) < 0) { 51 perror("sigaction SIGUSR1"); 52 exit(1); 53 } 54 if (sigaction(SIGALRM, &act, NULL) < 0) { 55 perror("sigaction SIGALRM"); 56 exit(1); 57 } 58 59 /* Don't do this for MAX_ATTEMPT, its simply too long */ 60 for(i = 0; i < 1000; i++) { 61 pid = fork(); 62 if (pid == -1) { 63 perror("fork"); 64 exit(1); 65 } 66 if (pid == 0) { 67 signal_self(ppid, SIGUSR1); 68 exit(1); 69 } else { 70 alarm(0); /* Disable any pending */ 71 alarm(2); 72 while (!signaled && !fail) 73 asm volatile("": : :"memory"); 74 if (!signaled) { 75 fprintf(stderr, "Didn't get signal from child\n"); 76 FAIL_IF(1); /* For the line number */ 77 } 78 /* Otherwise we'll loop too fast and fork() will eventually fail */ 79 waitpid(pid, NULL, 0); 80 } 81 } 82 83 for (i = 0; i < MAX_ATTEMPT; i++) { 84 long rc; 85 86 alarm(0); /* Disable any pending */ 87 signaled = 0; 88 alarm(TIMEOUT); 89 rc = signal_self(ppid, SIGUSR1); 90 if (rc) { 91 fprintf(stderr, "(%d) Fail reason: %d rc=0x%lx", 92 i, fail, rc); 93 FAIL_IF(1); /* For the line number */ 94 } 95 while (!signaled && !fail) 96 asm volatile("": : :"memory"); 97 if (!signaled) { 98 fprintf(stderr, "(%d) Fail reason: %d rc=0x%lx", 99 i, fail, rc); 100 FAIL_IF(1); /* For the line number */ 101 } 102 } 103 104 return 0; 105 } 106 107 int main(void) 108 { 109 test_harness_set_timeout(300); 110 return test_harness(test_signal, "signal"); 111 } 112