1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2000,2008 Oracle.  All rights reserved.
5 *
6 * $Id: util_sig.c,v 12.8 2008/01/08 20:58:08 bostic Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13static int	interrupt;
14static void	set_signal __P((int, int));
15static void	signal_handler __P((int));
16
17/*
18 * signal_handler --
19 *	Interrupt signal handler.
20 */
21static void
22signal_handler(signo)
23	int signo;
24{
25#ifndef HAVE_SIGACTION
26	/* Assume signal() is unreliable and reset it, first thing. */
27	set_signal(signo, 0);
28#endif
29	/* Some systems don't pass in the correct signal value -- check. */
30	if ((interrupt = signo) == 0)
31		interrupt = SIGINT;
32}
33
34/*
35 * set_signal
36 */
37static void
38set_signal(s, is_dflt)
39	int s, is_dflt;
40{
41	/*
42	 * Use sigaction if it's available, otherwise use signal().
43	 */
44#ifdef HAVE_SIGACTION
45	struct sigaction sa, osa;
46
47	sa.sa_handler = is_dflt ? SIG_DFL : signal_handler;
48	(void)sigemptyset(&sa.sa_mask);
49	sa.sa_flags = 0;
50	(void)sigaction(s, &sa, &osa);
51#else
52	(void)signal(s, is_dflt ? SIG_DFL : signal_handler);
53#endif
54}
55
56/*
57 * __db_util_siginit --
58 *
59 * PUBLIC: void __db_util_siginit __P((void));
60 */
61void
62__db_util_siginit()
63{
64	/*
65	 * Initialize the set of signals for which we want to clean up.
66	 * Generally, we try not to leave the shared regions locked if
67	 * we can.
68	 */
69#ifdef SIGHUP
70	set_signal(SIGHUP, 0);
71#endif
72#ifdef SIGINT
73	set_signal(SIGINT, 0);
74#endif
75#ifdef SIGPIPE
76	set_signal(SIGPIPE, 0);
77#endif
78#ifdef SIGTERM
79	set_signal(SIGTERM, 0);
80#endif
81}
82
83/*
84 * __db_util_interrupted --
85 *	Return if interrupted.
86 *
87 * PUBLIC: int __db_util_interrupted __P((void));
88 */
89int
90__db_util_interrupted()
91{
92	return (interrupt != 0);
93}
94
95/*
96 * __db_util_sigresend --
97 *
98 * PUBLIC: void __db_util_sigresend __P((void));
99 */
100void
101__db_util_sigresend()
102{
103	/* Resend any caught signal. */
104	if (interrupt != 0) {
105		set_signal(interrupt, 1);
106
107		(void)raise(interrupt);
108		/* NOTREACHED */
109	}
110}
111