xref: /openbsd/regress/sys/kern/signal/sigfpe/sigfpe.c (revision d89ec533)
1 /* Placed in the public domain by Todd C. Miller on April 30, 2002 */
2 
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <signal.h>
6 #include <unistd.h>
7 
8 void check_oflow(void);
9 void check_div0(int);
10 void timedout(int);
11 void div0_handler(int);
12 __dead void usage(void);
13 
14 /*
15  * Check signal(SIGFPE, SIG_IGN) for overflow and divide by zero.
16  */
17 int
18 main(int argc, char **argv)
19 {
20 	int ch, oflag, zflag;
21 
22 	oflag = zflag = 0;
23 	while ((ch = getopt(argc, argv, "oz")) != -1) {
24 		switch (ch) {
25 		case 'o':
26 			oflag = 1;
27 			break;
28 		case 'z':
29 			zflag = 1;
30 			break;
31 		}
32 	}
33 
34 	if (oflag && zflag)
35 		usage();
36 
37 	signal(SIGFPE, div0_handler);
38 	signal(SIGALRM, timedout);
39 
40 	if (oflag)
41 		check_oflow();
42 	else
43 		check_div0(0);
44 
45 	exit(0);
46 }
47 
48 void
49 check_oflow(void)
50 {
51 	double d, od;
52 
53 	od = 0;
54 	d = 256;
55 	do {
56 		od = d;
57 		alarm(10);
58 		d *= d;
59 		alarm(0);
60 	} while (d != od);
61 }
62 
63 void
64 check_div0(int zero)
65 {
66 	int i;
67 
68 	alarm(10);
69 	i = 1 / zero;
70 	alarm(0);
71 }
72 
73 void
74 timedout(int sig)
75 {
76 	_exit(1);
77 }
78 
79 void
80 div0_handler(int sig)
81 {
82 	_exit(0);
83 }
84 
85 __dead void
86 usage(void)
87 {
88 	extern char *__progname;
89 
90 	(void)fprintf(stderr, "usage: %s -o | -z\n", __progname);
91 	exit(1);
92 }
93