Linux-libre 5.4.48-gnu
[librecmc/linux-libre.git] / tools / testing / selftests / powerpc / signal / signal.c
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 }