1 /* signal.c - signal handling
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3 * 2005 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of either
10 * - the GNU Lesser General Public License as published by the Free
11 * Software Foundation; either version 3 of the License, or (at
12 * your option) any later version.
16 * - the GNU General Public License as published by the Free
17 * Software Foundation; either version 2 of the License, or (at
18 * your option) any later version.
20 * or both in parallel, as here.
22 * This file is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, see <https://www.gnu.org/licenses/>.
45 #ifndef HAVE_DOSISH_SYSTEM
46 static volatile int caught_fatal_sig;
47 static volatile int caught_sigusr1;
49 static void (*cleanup_fnc)(void);
52 #ifndef HAVE_DOSISH_SYSTEM
54 init_one_signal (int sig, RETSIGTYPE (*handler)(int), int check_ign )
56 # ifdef HAVE_SIGACTION
57 struct sigaction oact, nact;
61 /* we don't want to change an IGN handler */
62 sigaction (sig, NULL, &oact );
63 if (oact.sa_handler == SIG_IGN )
67 nact.sa_handler = handler;
68 sigemptyset (&nact.sa_mask);
70 sigaction ( sig, &nact, NULL);
72 RETSIGTYPE (*ohandler)(int);
74 ohandler = signal (sig, handler);
75 if (check_ign && ohandler == SIG_IGN)
77 /* Change it back if it was already set to IGN */
78 signal (sig, SIG_IGN);
82 #endif /*!HAVE_DOSISH_SYSTEM*/
84 #ifndef HAVE_DOSISH_SYSTEM
86 get_signal_name( int signum )
88 /* Note that we can't use strsignal(), because it is not
90 #if HAVE_DECL_SYS_SIGLIST && defined(NSIG)
91 return (signum >= 0 && signum < NSIG) ? sys_siglist[signum] : "?";
96 #endif /*!HAVE_DOSISH_SYSTEM*/
98 #ifndef HAVE_DOSISH_SYSTEM
100 got_fatal_signal (int sig)
104 if (caught_fatal_sig)
106 caught_fatal_sig = 1;
110 /* Better don't translate these messages. */
111 (void)write (2, "\n", 1 );
112 s = log_get_prefix (NULL);
114 (void)write(2, s, strlen (s));
115 (void)write (2, ": signal ", 9 );
116 s = get_signal_name(sig);
118 (void) write (2, s, strlen(s) );
121 /* We are in a signal handler so we can't use any kind of printf
122 even not sprintf. So we use a straightforward algorithm. We
123 got a report that on one particular system, raising a signal
124 while in this handler, the parameter SIG get sclobbered and
125 things are messed up because we modify its value. Although
126 this is a bug in that system, we will protect against it. */
127 if (sig < 0 || sig >= 100000)
128 (void)write (2, "?", 1);
133 for (value=sig,i=10000; i; i /= 10)
135 if (value >= i || ((any || i==1) && !(value/i)))
137 (void)write (2, &"0123456789"[value/i], 1);
145 (void)write (2, " caught ... exiting\n", 20);
147 /* Reset action to default action and raise signal again */
148 init_one_signal (sig, SIG_DFL, 0);
149 /* Fixme: remove_lockfiles ();*/
152 #endif /* __riscos__ */
155 #endif /*!HAVE_DOSISH_SYSTEM*/
157 #ifndef HAVE_DOSISH_SYSTEM
159 got_usr_signal (int sig)
164 #endif /*!HAVE_DOSISH_SYSTEM*/
167 gnupg_init_signals (int mode, void (*fast_cleanup)(void))
171 cleanup_fnc = fast_cleanup;
172 #ifndef HAVE_DOSISH_SYSTEM
173 init_one_signal (SIGINT, got_fatal_signal, 1 );
174 init_one_signal (SIGHUP, got_fatal_signal, 1 );
175 init_one_signal (SIGTERM, got_fatal_signal, 1 );
176 init_one_signal (SIGQUIT, got_fatal_signal, 1 );
177 init_one_signal (SIGSEGV, got_fatal_signal, 1 );
178 init_one_signal (SIGUSR1, got_usr_signal, 0 );
179 init_one_signal (SIGPIPE, SIG_IGN, 0 );
187 #ifdef HAVE_DOSISH_SYSTEM
189 #else /*!HAVE_DOSISH_SYSTEM*/
190 static int is_blocked;
191 #ifdef HAVE_SIGPROCMASK
192 static sigset_t oldmask;
199 log_bug ("signals are already blocked\n");
200 sigfillset( &newmask );
201 sigprocmask( SIG_BLOCK, &newmask, &oldmask );
207 log_bug("signals are not blocked\n");
208 sigprocmask (SIG_SETMASK, &oldmask, NULL);
211 #else /*!HAVE_SIGPROCMASK*/
212 static void (*disposition[MAXSIG])();
218 log_bug("signals are already blocked\n");
219 for (sig=1; sig < MAXSIG; sig++)
221 disposition[sig] = sigset (sig, SIG_HOLD);
228 log_bug ("signals are not blocked\n");
229 for (sig=1; sig < MAXSIG; sig++) {
230 sigset (sig, disposition[sig]);
234 #endif /*!HAVE_SIGPROCMASK*/
235 #endif /*!HAVE_DOSISH_SYSTEM*/
240 gnupg_block_all_signals ()
246 gnupg_unblock_all_signals ()