xref: /openbsd-src/regress/sys/kern/signal/sigfpe/sigfpe.c (revision dc5cab49410370e20f8c5d129cd9ac7990ea8315)
1c062f46dSmillert /* Placed in the public domain by Todd C. Miller on April 30, 2002 */
2c062f46dSmillert 
30de7ebcaSmillert #include <stdio.h>
40de7ebcaSmillert #include <stdlib.h>
50de7ebcaSmillert #include <signal.h>
60de7ebcaSmillert #include <unistd.h>
70de7ebcaSmillert 
80de7ebcaSmillert void check_oflow(void);
96f459a10Smiod void check_div0(int);
100de7ebcaSmillert void timedout(int);
11*dc5cab49Spirofti void div0_handler(int);
120de7ebcaSmillert __dead void usage(void);
130de7ebcaSmillert 
140de7ebcaSmillert /*
150de7ebcaSmillert  * Check signal(SIGFPE, SIG_IGN) for overflow and divide by zero.
160de7ebcaSmillert  */
170de7ebcaSmillert int
main(int argc,char ** argv)180de7ebcaSmillert main(int argc, char **argv)
190de7ebcaSmillert {
200de7ebcaSmillert 	int ch, oflag, zflag;
210de7ebcaSmillert 
220de7ebcaSmillert 	oflag = zflag = 0;
230de7ebcaSmillert 	while ((ch = getopt(argc, argv, "oz")) != -1) {
240de7ebcaSmillert 		switch (ch) {
250de7ebcaSmillert 		case 'o':
260de7ebcaSmillert 			oflag = 1;
270de7ebcaSmillert 			break;
280de7ebcaSmillert 		case 'z':
290de7ebcaSmillert 			zflag = 1;
300de7ebcaSmillert 			break;
310de7ebcaSmillert 		}
320de7ebcaSmillert 	}
330de7ebcaSmillert 
340de7ebcaSmillert 	if (oflag && zflag)
350de7ebcaSmillert 		usage();
360de7ebcaSmillert 
37*dc5cab49Spirofti 	signal(SIGFPE, div0_handler);
380de7ebcaSmillert 	signal(SIGALRM, timedout);
390de7ebcaSmillert 
400de7ebcaSmillert 	if (oflag)
410de7ebcaSmillert 		check_oflow();
420de7ebcaSmillert 	else
436f459a10Smiod 		check_div0(0);
440de7ebcaSmillert 
450de7ebcaSmillert 	exit(0);
460de7ebcaSmillert }
470de7ebcaSmillert 
480de7ebcaSmillert void
check_oflow(void)490de7ebcaSmillert check_oflow(void)
500de7ebcaSmillert {
510de7ebcaSmillert 	double d, od;
520de7ebcaSmillert 
530de7ebcaSmillert 	od = 0;
540de7ebcaSmillert 	d = 256;
550de7ebcaSmillert 	do {
560de7ebcaSmillert 		od = d;
570de7ebcaSmillert 		alarm(10);
580de7ebcaSmillert 		d *= d;
590de7ebcaSmillert 		alarm(0);
600de7ebcaSmillert 	} while (d != od);
610de7ebcaSmillert }
620de7ebcaSmillert 
630de7ebcaSmillert void
check_div0(int zero)646f459a10Smiod check_div0(int zero)
650de7ebcaSmillert {
660de7ebcaSmillert 	int i;
670de7ebcaSmillert 
680de7ebcaSmillert 	alarm(10);
696f459a10Smiod 	i = 1 / zero;
700de7ebcaSmillert 	alarm(0);
710de7ebcaSmillert }
720de7ebcaSmillert 
730de7ebcaSmillert void
timedout(int sig)740de7ebcaSmillert timedout(int sig)
750de7ebcaSmillert {
760de7ebcaSmillert 	_exit(1);
770de7ebcaSmillert }
780de7ebcaSmillert 
79*dc5cab49Spirofti void
div0_handler(int sig)80*dc5cab49Spirofti div0_handler(int sig)
81*dc5cab49Spirofti {
82*dc5cab49Spirofti 	_exit(0);
83*dc5cab49Spirofti }
84*dc5cab49Spirofti 
850de7ebcaSmillert __dead void
usage(void)860de7ebcaSmillert usage(void)
870de7ebcaSmillert {
880de7ebcaSmillert 	extern char *__progname;
890de7ebcaSmillert 
900de7ebcaSmillert 	(void)fprintf(stderr, "usage: %s -o | -z\n", __progname);
910de7ebcaSmillert 	exit(1);
920de7ebcaSmillert }
93