Revert "usbd - Do not start moused by default when a usb mouse is connected"
[dragonfly.git] / contrib / sendmail-8.14 / libsm / signal.c
blobce2e242fabf3475aacab251646b4ce1115d86759
1 /*
2 * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3 * All rights reserved.
5 * By using this file, you agree to the terms and conditions set
6 * forth in the LICENSE file which can be found at the top level of
7 * the sendmail distribution.
8 */
10 #include <sm/gen.h>
11 SM_RCSID("@(#)$Id: signal.c,v 1.17 2005/06/14 23:07:20 ca Exp $")
13 #if SM_CONF_SETITIMER
14 # include <sm/time.h>
15 #endif /* SM_CONF_SETITIMER */
16 #include <errno.h>
17 #include <stdlib.h>
18 #include <time.h>
19 #include <unistd.h>
20 #include <sm/clock.h>
21 #include <sm/signal.h>
22 #include <signal.h>
23 #include <sm/string.h>
25 unsigned int volatile InCriticalSection; /* >0 if inside critical section */
26 int volatile PendingSignal; /* pending signal to resend */
29 ** SM_SIGNAL -- set a signal handler
31 ** This is essentially old BSD "signal(3)".
33 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
34 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
35 ** DOING.
38 sigfunc_t
39 sm_signal(sig, handler)
40 int sig;
41 sigfunc_t handler;
43 # if defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3))
44 struct sigaction n, o;
45 # endif /* defined(SA_RESTART) || (!defined(SYS5SIGNALS) && !defined(BSD4_3)) */
48 ** First, try for modern signal calls
49 ** and restartable syscalls
52 # ifdef SA_RESTART
53 (void) memset(&n, '\0', sizeof n);
54 # if USE_SA_SIGACTION
55 n.sa_sigaction = (void(*)(int, siginfo_t *, void *)) handler;
56 n.sa_flags = SA_RESTART|SA_SIGINFO;
57 # else /* USE_SA_SIGACTION */
58 n.sa_handler = handler;
59 n.sa_flags = SA_RESTART;
60 # endif /* USE_SA_SIGACTION */
61 if (sigaction(sig, &n, &o) < 0)
62 return SIG_ERR;
63 return o.sa_handler;
64 # else /* SA_RESTART */
67 ** Else check for SYS5SIGNALS or
68 ** BSD4_3 signals
71 # if defined(SYS5SIGNALS) || defined(BSD4_3)
72 # ifdef BSD4_3
73 return signal(sig, handler);
74 # else /* BSD4_3 */
75 return sigset(sig, handler);
76 # endif /* BSD4_3 */
77 # else /* defined(SYS5SIGNALS) || defined(BSD4_3) */
80 ** Finally, if nothing else is available,
81 ** go for a default
84 (void) memset(&n, '\0', sizeof n);
85 n.sa_handler = handler;
86 if (sigaction(sig, &n, &o) < 0)
87 return SIG_ERR;
88 return o.sa_handler;
89 # endif /* defined(SYS5SIGNALS) || defined(BSD4_3) */
90 # endif /* SA_RESTART */
93 ** SM_BLOCKSIGNAL -- hold a signal to prevent delivery
95 ** Parameters:
96 ** sig -- the signal to block.
98 ** Returns:
99 ** 1 signal was previously blocked
100 ** 0 signal was not previously blocked
101 ** -1 on failure.
105 sm_blocksignal(sig)
106 int sig;
108 # ifdef BSD4_3
109 # ifndef sigmask
110 # define sigmask(s) (1 << ((s) - 1))
111 # endif /* ! sigmask */
112 return (sigblock(sigmask(sig)) & sigmask(sig)) != 0;
113 # else /* BSD4_3 */
114 # ifdef ALTOS_SYSTEM_V
115 sigfunc_t handler;
117 handler = sigset(sig, SIG_HOLD);
118 if (handler == SIG_ERR)
119 return -1;
120 else
121 return handler == SIG_HOLD;
122 # else /* ALTOS_SYSTEM_V */
123 sigset_t sset, oset;
125 (void) sigemptyset(&sset);
126 (void) sigaddset(&sset, sig);
127 if (sigprocmask(SIG_BLOCK, &sset, &oset) < 0)
128 return -1;
129 else
130 return sigismember(&oset, sig);
131 # endif /* ALTOS_SYSTEM_V */
132 # endif /* BSD4_3 */
135 ** SM_RELEASESIGNAL -- release a held signal
137 ** Parameters:
138 ** sig -- the signal to release.
140 ** Returns:
141 ** 1 signal was previously blocked
142 ** 0 signal was not previously blocked
143 ** -1 on failure.
147 sm_releasesignal(sig)
148 int sig;
150 # ifdef BSD4_3
151 return (sigsetmask(sigblock(0) & ~sigmask(sig)) & sigmask(sig)) != 0;
152 # else /* BSD4_3 */
153 # ifdef ALTOS_SYSTEM_V
154 sigfunc_t handler;
156 handler = sigset(sig, SIG_HOLD);
157 if (sigrelse(sig) < 0)
158 return -1;
159 else
160 return handler == SIG_HOLD;
161 # else /* ALTOS_SYSTEM_V */
162 sigset_t sset, oset;
164 (void) sigemptyset(&sset);
165 (void) sigaddset(&sset, sig);
166 if (sigprocmask(SIG_UNBLOCK, &sset, &oset) < 0)
167 return -1;
168 else
169 return sigismember(&oset, sig);
170 # endif /* ALTOS_SYSTEM_V */
171 # endif /* BSD4_3 */
174 ** PEND_SIGNAL -- Add a signal to the pending signal list
176 ** Parameters:
177 ** sig -- signal to add
179 ** Returns:
180 ** none.
182 ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD
183 ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE
184 ** DOING.
187 void
188 pend_signal(sig)
189 int sig;
191 int sigbit;
192 int save_errno = errno;
193 #if SM_CONF_SETITIMER
194 struct itimerval clr;
195 #endif /* SM_CONF_SETITIMER */
198 ** Don't want to interrupt something critical, hence delay
199 ** the alarm for one second. Hopefully, by then we
200 ** will be out of the critical section. If not, then
201 ** we will just delay again. The events to be run will
202 ** still all be run, maybe just a little bit late.
205 switch (sig)
207 case SIGHUP:
208 sigbit = PEND_SIGHUP;
209 break;
211 case SIGINT:
212 sigbit = PEND_SIGINT;
213 break;
215 case SIGTERM:
216 sigbit = PEND_SIGTERM;
217 break;
219 case SIGUSR1:
220 sigbit = PEND_SIGUSR1;
221 break;
223 case SIGALRM:
224 /* don't have to pend these */
225 sigbit = 0;
226 break;
228 default:
229 /* If we get here, we are in trouble */
230 abort();
232 /* NOTREACHED */
233 /* shut up stupid compiler warning on HP-UX 11 */
234 sigbit = 0;
235 break;
238 if (sigbit != 0)
239 PendingSignal |= sigbit;
240 (void) sm_signal(SIGALRM, sm_tick);
241 #if SM_CONF_SETITIMER
242 clr.it_interval.tv_sec = 0;
243 clr.it_interval.tv_usec = 0;
244 clr.it_value.tv_sec = 1;
245 clr.it_value.tv_usec = 0;
246 (void) setitimer(ITIMER_REAL, &clr, NULL);
247 #else /* SM_CONF_SETITIMER */
248 (void) alarm(1);
249 #endif /* SM_CONF_SETITIMER */
250 errno = save_errno;
253 ** SM_ALLSIGNALS -- act on all signals
255 ** Parameters:
256 ** block -- whether to block or release all signals.
258 ** Returns:
259 ** none.
262 void
263 sm_allsignals(block)
264 bool block;
266 # ifdef BSD4_3
267 # ifndef sigmask
268 # define sigmask(s) (1 << ((s) - 1))
269 # endif /* ! sigmask */
270 if (block)
272 int mask = 0;
274 mask |= sigmask(SIGALRM);
275 mask |= sigmask(SIGCHLD);
276 mask |= sigmask(SIGHUP);
277 mask |= sigmask(SIGINT);
278 mask |= sigmask(SIGTERM);
279 mask |= sigmask(SIGUSR1);
281 (void) sigblock(mask);
283 else
284 sigsetmask(0);
285 # else /* BSD4_3 */
286 # ifdef ALTOS_SYSTEM_V
287 if (block)
289 (void) sigset(SIGALRM, SIG_HOLD);
290 (void) sigset(SIGCHLD, SIG_HOLD);
291 (void) sigset(SIGHUP, SIG_HOLD);
292 (void) sigset(SIGINT, SIG_HOLD);
293 (void) sigset(SIGTERM, SIG_HOLD);
294 (void) sigset(SIGUSR1, SIG_HOLD);
296 else
298 (void) sigset(SIGALRM, SIG_DFL);
299 (void) sigset(SIGCHLD, SIG_DFL);
300 (void) sigset(SIGHUP, SIG_DFL);
301 (void) sigset(SIGINT, SIG_DFL);
302 (void) sigset(SIGTERM, SIG_DFL);
303 (void) sigset(SIGUSR1, SIG_DFL);
305 # else /* ALTOS_SYSTEM_V */
306 sigset_t sset;
308 (void) sigemptyset(&sset);
309 (void) sigaddset(&sset, SIGALRM);
310 (void) sigaddset(&sset, SIGCHLD);
311 (void) sigaddset(&sset, SIGHUP);
312 (void) sigaddset(&sset, SIGINT);
313 (void) sigaddset(&sset, SIGTERM);
314 (void) sigaddset(&sset, SIGUSR1);
315 (void) sigprocmask(block ? SIG_BLOCK : SIG_UNBLOCK, &sset, NULL);
316 # endif /* ALTOS_SYSTEM_V */
317 # endif /* BSD4_3 */
320 ** SM_SIGNAL_NOOP -- A signal no-op function
322 ** Parameters:
323 ** sig -- signal received
325 ** Returns:
326 ** SIGFUNC_RETURN
329 /* ARGSUSED */
330 SIGFUNC_DECL
331 sm_signal_noop(sig)
332 int sig;
334 int save_errno = errno;
336 FIX_SYSV_SIGNAL(sig, sm_signal_noop);
337 errno = save_errno;
338 return SIGFUNC_RETURN;