2 * Copyright (c) 2010 Your File System Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * This is a pthread compatible signal handling system. It doesn't have any
28 * restrictions on the code which can be called from a signal handler, as handlers
29 * are processed in a dedicated thread, rather than as part of the async signal
32 * Applications wishing to use this system must call opr_softsig_Init _before_
33 * starting any other threads. After this, all signal handlers must be registered
34 * using opr_softsig_Register.
37 #include <afsconfig.h>
38 #include <afs/param.h>
46 void (*handler) (int);
50 softsigSignalSet(sigset_t *set)
53 sigdelset(set, SIGKILL);
54 sigdelset(set, SIGSTOP);
55 sigdelset(set, SIGCONT);
56 sigdelset(set, SIGABRT);
57 sigdelset(set, SIGBUS);
58 sigdelset(set, SIGFPE);
59 sigdelset(set, SIGILL);
60 sigdelset(set, SIGPIPE);
61 sigdelset(set, SIGSEGV);
62 sigdelset(set, SIGTRAP);
66 signalHandler(void *arg)
71 softsigSignalSet(&set);
73 opr_Verify(sigwait(&set, &receivedSignal) == 0);
74 opr_Verify(sigismember(&set, receivedSignal) == 1);
75 if (handlers[receivedSignal].handler != NULL) {
76 handlers[receivedSignal].handler(receivedSignal);
83 ExitHandler(int signal)
89 StopHandler(int signal)
91 kill(getpid(), SIGSTOP);
95 * Register a soft signal handler
97 * Soft signal handlers may only be registered for async signals.
100 * The signal to register a handler for.
102 * The handler function to register, or NULL, to clear a signal handler.
105 * EINVAL if the signal given isn't one for which we can register a soft
110 opr_softsig_Register(int sig, void (*handler)(int))
114 softsigSignalSet(&set);
116 /* Check that the supplied signal is handled by softsig. */
117 if (sigismember(&set, sig)) {
118 handlers[sig].handler = handler;
126 * Initialise the soft signal system
128 * This call initialises the soft signal system. It provides default handlers for
129 * SIGINT and SIGTSTP which preserve the operating system behaviour (terminating
130 * and stopping the process, respectively).
132 * opr_softsig_Init() must be called before any threads are created, as it sets
133 * up a global signal mask on the parent process that is then inherited by all
138 opr_softsig_Init(void)
141 pthread_t handlerThread;
143 /* Block all signals in the main thread, and in any threads which are created
144 * after us. Only the signal handler thread will receive signals. */
145 softsigSignalSet(&set);
146 pthread_sigmask(SIG_BLOCK, &set, NULL);
148 /* Register a few handlers so that we keep the usual behaviour for CTRL-C and
149 * CTRL-Z, unless the application replaces them. */
150 opr_Verify(opr_softsig_Register(SIGINT, ExitHandler) == 0);
151 opr_Verify(opr_softsig_Register(SIGTERM, ExitHandler) == 0);
152 opr_Verify(opr_softsig_Register(SIGQUIT, ExitHandler) == 0);
153 opr_Verify(opr_softsig_Register(SIGTSTP, StopHandler) == 0);
155 /* Create a signal handler thread which will respond to any incoming signals
157 opr_Verify(pthread_create(&handlerThread, NULL, signalHandler, NULL) == 0);
158 opr_Verify(pthread_detach(handlerThread) == 0);