sig.c revision 31921
131921Sbrian/*- 231921Sbrian * Copyright (c) 1997 Brian Somers <brian@Awfulhak.org> 331921Sbrian * All rights reserved. 431921Sbrian * 531921Sbrian * Redistribution and use in source and binary forms, with or without 631921Sbrian * modification, are permitted provided that the following conditions 731921Sbrian * are met: 831921Sbrian * 1. Redistributions of source code must retain the above copyright 931921Sbrian * notice, this list of conditions and the following disclaimer. 1031921Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1131921Sbrian * notice, this list of conditions and the following disclaimer in the 1231921Sbrian * documentation and/or other materials provided with the distribution. 1331921Sbrian * 1431921Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1531921Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1631921Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1731921Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1831921Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1931921Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2031921Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2131921Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2231921Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2331921Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2431921Sbrian * SUCH DAMAGE. 2531921Sbrian * 2631921Sbrian * $Id$ 2723840Sbrian */ 2823840Sbrian 2923840Sbrian#include <sys/types.h> 3030715Sbrian 3123840Sbrian#include <signal.h> 3230715Sbrian 3331343Sbrian#include "command.h" 3423840Sbrian#include "mbuf.h" 3523840Sbrian#include "log.h" 3631343Sbrian#include "sig.h" 3723840Sbrian 3823840Sbrianstatic caused[NSIG]; /* An array of pending signals */ 3923840Sbrianstatic sig_type handler[NSIG]; /* all start at SIG_DFL */ 4023840Sbrian 4123840Sbrian 4223840Sbrian/* Record a signal in the "caused" array */ 4323840Sbrian 4428679Sbrianstatic void 4528679Sbriansignal_recorder(int sig) 4628679Sbrian{ 4728679Sbrian caused[sig - 1]++; 4823840Sbrian} 4923840Sbrian 5023840Sbrian 5123840Sbrian/* 5228679Sbrian * Set up signal_recorder, and record handler as the function to ultimately 5328679Sbrian * call in handle_signal() 5423840Sbrian*/ 5523840Sbrian 5628679Sbriansig_type 5728679Sbrianpending_signal(int sig, sig_type fn) 5828679Sbrian{ 5928679Sbrian sig_type Result; 6023840Sbrian 6128679Sbrian if (sig <= 0 || sig > NSIG) { 6228679Sbrian /* Oops - we must be a bit out of date (too many sigs ?) */ 6328679Sbrian LogPrintf(LogALERT, "Eeek! %s:%s: I must be out of date!\n", 6428679Sbrian __FILE__, __LINE__); 6528679Sbrian return signal(sig, fn); 6628679Sbrian } 6728679Sbrian Result = handler[sig - 1]; 6828679Sbrian if (fn == SIG_DFL || fn == SIG_IGN) { 6928679Sbrian signal(sig, fn); 7028679Sbrian handler[sig - 1] = (sig_type) 0; 7128679Sbrian } else { 7228679Sbrian handler[sig - 1] = fn; 7328679Sbrian signal(sig, signal_recorder); 7428679Sbrian } 7528679Sbrian caused[sig - 1] = 0; 7628679Sbrian return Result; 7723840Sbrian} 7823840Sbrian 7923840Sbrian 8023840Sbrian/* Call the handlers for any pending signals */ 8123840Sbrian 8228679Sbrianvoid 8328679Sbrianhandle_signals() 8428679Sbrian{ 8528679Sbrian int sig; 8628679Sbrian int got; 8723840Sbrian 8828679Sbrian do { 8928679Sbrian got = 0; 9028679Sbrian for (sig = 0; sig < NSIG; sig++) 9128679Sbrian if (caused[sig]) { 9228679Sbrian caused[sig]--; 9328679Sbrian got++; 9428679Sbrian (*handler[sig]) (sig + 1); 9528679Sbrian } 9628679Sbrian } while (got); 9723840Sbrian} 98