Branch data Line data Source code
1 : : /*
2 : : Unix SMB/CIFS implementation.
3 : : signal handling functions
4 : :
5 : : Copyright (C) Andrew Tridgell 1998
6 : :
7 : : This program is free software; you can redistribute it and/or modify
8 : : it under the terms of the GNU General Public License as published by
9 : : the Free Software Foundation; either version 3 of the License, or
10 : : (at your option) any later version.
11 : :
12 : : This program is distributed in the hope that it will be useful,
13 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : : GNU General Public License for more details.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : : */
20 : :
21 : : #include "util/util.h"
22 : : #include <sys/types.h>
23 : : #include <sys/wait.h>
24 : :
25 : :
26 : : /**
27 : : * @file
28 : : * @brief Signal handling
29 : : */
30 : :
31 : : /****************************************************************************
32 : : Catch child exits and reap the child zombie status.
33 : : ****************************************************************************/
34 : :
35 : 0 : static void sig_cld(int signum)
36 : : {
37 [ # # ]: 0 : while (waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0)
38 : : ;
39 : :
40 : : /*
41 : : * Turns out it's *really* important not to
42 : : * restore the signal handler here if we have real POSIX
43 : : * signal handling. If we do, then we get the signal re-delivered
44 : : * immediately - hey presto - instant loop ! JRA.
45 : : */
46 : :
47 : : #if !defined(HAVE_SIGACTION)
48 : : CatchSignal(SIGCLD, sig_cld);
49 : : #endif
50 : 0 : }
51 : :
52 : : /****************************************************************************
53 : : catch child exits - leave status;
54 : : ****************************************************************************/
55 : :
56 : 0 : static void sig_cld_leave_status(int signum)
57 : : {
58 : : /*
59 : : * Turns out it's *really* important not to
60 : : * restore the signal handler here if we have real POSIX
61 : : * signal handling. If we do, then we get the signal re-delivered
62 : : * immediately - hey presto - instant loop ! JRA.
63 : : */
64 : :
65 : : #if !defined(HAVE_SIGACTION)
66 : : CatchSignal(SIGCLD, sig_cld_leave_status);
67 : : #endif
68 : 0 : }
69 : :
70 : : /**
71 : : Block sigs.
72 : : **/
73 : :
74 : 0 : void BlockSignals(bool block, int signum)
75 : : {
76 : : #ifdef HAVE_SIGPROCMASK
77 : : sigset_t set;
78 : 0 : sigemptyset(&set);
79 : 0 : sigaddset(&set,signum);
80 [ # # ]: 0 : sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
81 : : #elif defined(HAVE_SIGBLOCK)
82 : : if (block) {
83 : : sigblock(sigmask(signum));
84 : : } else {
85 : : sigsetmask(siggetmask() & ~sigmask(signum));
86 : : }
87 : : #else
88 : : /* yikes! This platform can't block signals? */
89 : : static int done;
90 : : if (!done) {
91 : : DEBUG(0,("WARNING: No signal blocking available\n"));
92 : : done=1;
93 : : }
94 : : #endif
95 : 0 : }
96 : :
97 : : /**
98 : : Catch a signal. This should implement the following semantics:
99 : :
100 : : 1) The handler remains installed after being called.
101 : : 2) The signal should be blocked during handler execution.
102 : : **/
103 : :
104 : 0 : void (*CatchSignal(int signum,void (*handler)(int )))(int)
105 : : {
106 : : #ifdef HAVE_SIGACTION
107 : : struct sigaction act;
108 : : struct sigaction oldact;
109 : :
110 : 0 : ZERO_STRUCT(act);
111 : :
112 : 0 : act.sa_handler = handler;
113 : : #ifdef SA_RESTART
114 : : /*
115 : : * We *want* SIGALRM to interrupt a system call.
116 : : */
117 [ # # ]: 0 : if(signum != SIGALRM)
118 : 0 : act.sa_flags = SA_RESTART;
119 : : #endif
120 : 0 : sigemptyset(&act.sa_mask);
121 : 0 : sigaddset(&act.sa_mask,signum);
122 : 0 : sigaction(signum,&act,&oldact);
123 : 0 : return oldact.sa_handler;
124 : : #else /* !HAVE_SIGACTION */
125 : : /* FIXME: need to handle sigvec and systems with broken signal() */
126 : : return signal(signum, handler);
127 : : #endif
128 : : }
129 : :
130 : : /**
131 : : Ignore SIGCLD via whatever means is necessary for this OS.
132 : : **/
133 : :
134 : 0 : void CatchChild(void)
135 : : {
136 : 0 : CatchSignal(SIGCLD, sig_cld);
137 : 0 : }
138 : :
139 : : /**
140 : : Catch SIGCLD but leave the child around so it's status can be reaped.
141 : : **/
142 : :
143 : 0 : void CatchChildLeaveStatus(void)
144 : : {
145 : 0 : CatchSignal(SIGCLD, sig_cld_leave_status);
146 : 0 : }
|