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