sig.c revision 50479
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 * 2650479Speter * $FreeBSD: head/usr.sbin/ppp/sig.c 50479 1999-08-28 01:35:59Z peter $ 2723840Sbrian */ 2823840Sbrian 2923840Sbrian#include <sys/types.h> 3030715Sbrian 3123840Sbrian#include <signal.h> 3230715Sbrian 3323840Sbrian#include "log.h" 3431343Sbrian#include "sig.h" 3523840Sbrian 3634331Sbrianstatic int caused[NSIG]; /* An array of pending signals */ 3745126Sbrianstatic int necessary; /* Anything set ? */ 3823840Sbrianstatic sig_type handler[NSIG]; /* all start at SIG_DFL */ 3923840Sbrian 4023840Sbrian 4123840Sbrian/* Record a signal in the "caused" array */ 4223840Sbrian 4328679Sbrianstatic void 4428679Sbriansignal_recorder(int sig) 4528679Sbrian{ 4628679Sbrian caused[sig - 1]++; 4745126Sbrian necessary = 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 5736285Sbriansig_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 ?) */ 6336285Sbrian log_Printf(LogALERT, "Eeek! %s:%d: 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 8245126Sbrianint 8336285Sbriansig_Handle() 8428679Sbrian{ 8528679Sbrian int sig; 8628679Sbrian int got; 8745126Sbrian int result; 8823840Sbrian 8945126Sbrian result = 0; 9045126Sbrian if (necessary) { 9145126Sbrian /* We've *probably* got something in `caused' set */ 9245126Sbrian necessary = 0; 9345126Sbrian /* `necessary' might go back to 1 while we're in here.... */ 9445126Sbrian do { 9545126Sbrian got = 0; 9645126Sbrian for (sig = 0; sig < NSIG; sig++) 9745126Sbrian if (caused[sig]) { 9845126Sbrian caused[sig]--; 9945126Sbrian got++; 10045126Sbrian result++; 10145126Sbrian (*handler[sig])(sig + 1); 10245126Sbrian } 10345126Sbrian } while (got); 10445126Sbrian } 10545126Sbrian 10645126Sbrian return result; 10723840Sbrian} 108