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