xref: /minix/minix/tests/test57.c (revision 83133719)
1 
2 /* This test tests whether registers are correctly restored after a
3  * signal handler is executed. The assembly file (test57loop.S) puts
4  * 'random' values in the registers, and the C code checks whether
5  * these values are the same, before and after the signal handler.
6  */
7 
8 #define _POSIX_SOURCE 1
9 
10 #include <stdio.h>
11 #include <signal.h>
12 #include <err.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 
16 #include <sys/types.h>
17 #include <sys/wait.h>
18 
19 #define SIGNAL SIGUSR1
20 
21 volatile int remaining_invocations = 2, handler_level = 0;
22 
23 void check_context_loop(void);
24 
25 #define REGS 8	/* how many registers pusha and popa save. */
26 
27 #define ESP 3	/* where is esp saved? */
28 
29 unsigned long newstate[REGS], origstate[REGS];
30 
31 static void handler(int signal)
32 {
33 	int st;
34 	sigset_t set, oset;
35 	handler_level++;
36 	remaining_invocations--;
37 	if(remaining_invocations < 1)
38 		return;
39 	sigemptyset(&set);
40 	sigaddset(&set, SIGNAL);
41 	sigprocmask(SIG_UNBLOCK, &set,  &oset);
42 	wait(&st);
43 	handler_level--;
44 }
45 
46 int main(int argc, char *argv[])
47 {
48 	pid_t child_pid;
49 
50 	printf("Test 57 ");
51 
52 	if(signal(SIGNAL, handler) == SIG_ERR)
53 		err(1, "signal");
54 
55 	fflush(NULL);
56 
57 	if((child_pid=fork()) < 0)
58 		err(1, "fork");
59 
60 	if(child_pid == 0) {
61 		pid_t ppid = 0;
62 
63 		/* Keep signaling the parent until
64 		 * it disappears.
65 		 */
66 		while((ppid = getppid()) > 1) {
67 			if(kill(ppid, SIGNAL) < 0)
68 				err(1, "kill");
69 			sleep(1);
70 		}
71 
72 		exit(0);
73 	} else {
74 		int i;
75 		int err = 0;
76 
77 		check_context_loop();
78 
79 		/* correct 2nd esp for 'pusha' difference. */
80 		newstate[ESP] += REGS*4;
81 
82 		for(i = 0; i < REGS; i++) {
83 #if 0
84 			printf("%d %08lx %08lx diff  ",
85 				i, newstate[i], origstate[i]);
86 #endif
87 			if(newstate[i] != origstate[i]) {
88 				fprintf(stderr, "reg %d changed; "
89 					"found 0x%lx, expected 0x%lx\n",
90 					i, newstate[i], origstate[i]);
91 				err = 1;
92 			}
93 		}
94 
95 		if(!err) printf("ok\n");
96 
97 		exit(err);
98 	}
99 
100 	return 0;
101 }
102 
103