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