static sigjmp_buf fpe_env;


static void
fpe_handler(int signal, siginfo_t *w, void *a)
{
	siglongjmp(fpe_env, w->si_code);
	
}


void
try_division(int x, int y)
{
	struct sigaction act, old;
	int code;
	
	volatile int result;

	
	code = sigsetjmp(fpe_env, 1);
	if (code == 0) {
		
		act.sa_sigaction = fpe_handler;
		sigemptyset(&act.sa_mask);
		act.sa_flags = SA_SIGINFO;
		if (sigaction(SIGFPE, &act, &old) < 0) {
			perror();
			exit(1);
		}

		
		result = x / y;

		
		if (sigaction(SIGFPE, &old, NULL) < 0) {
			perror();
			exit(1);
		}

		printf(, x, y, result);
	} else {
		
		if (sigaction(SIGFPE, &old, NULL) < 0) {
			perror();
			exit(1);
		}

		
		switch (code) {
		case FPE_INTDIV: 
		case FPE_FLTDIV: 
			printf(, x, y);
			break;
		default:
			printf(, x, y);
			break;
		}
	}
}


int
main()
{
	try_division(-44, 0);
	try_division(-44, 5);
	try_division(0, 5);
	try_division(0, 0);
	try_division(INT_MIN, -1);
	return 0;
}