131921Sbrian/*- 2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3330449Seadler * 481957Sbrian * Copyright (c) 1997 - 1999, 2001 Brian Somers <brian@Awfulhak.org> 531921Sbrian * All rights reserved. 631921Sbrian * 731921Sbrian * Redistribution and use in source and binary forms, with or without 831921Sbrian * modification, are permitted provided that the following conditions 931921Sbrian * are met: 1031921Sbrian * 1. Redistributions of source code must retain the above copyright 1131921Sbrian * notice, this list of conditions and the following disclaimer. 1231921Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1331921Sbrian * notice, this list of conditions and the following disclaimer in the 1431921Sbrian * documentation and/or other materials provided with the distribution. 1531921Sbrian * 1631921Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1731921Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1831921Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1931921Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2031921Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2131921Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2231921Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2331921Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2431921Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2531921Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2631921Sbrian * SUCH DAMAGE. 2731921Sbrian * 2850479Speter * $FreeBSD: stable/11/usr.sbin/ppp/sig.c 330449 2018-03-05 07:26:05Z eadler $ 2923840Sbrian */ 3023840Sbrian 3197140Sbrian#include <sys/types.h> 3297140Sbrian 3323840Sbrian#include <signal.h> 3430715Sbrian 3523840Sbrian#include "log.h" 3631343Sbrian#include "sig.h" 3723840Sbrian 3834331Sbrianstatic int caused[NSIG]; /* An array of pending signals */ 3945126Sbrianstatic int necessary; /* Anything set ? */ 4023840Sbrianstatic sig_type handler[NSIG]; /* all start at SIG_DFL */ 4123840Sbrian 4223840Sbrian 4381957Sbrian/* 4481957Sbrian * Record a signal in the "caused" array 4581957Sbrian * 4681957Sbrian * This function is the only thing actually called in signal context. It 4781957Sbrian * records that a signal has been caused and that sig_Handle() should be 4881957Sbrian * called (in non-signal context) as soon as possible to process that 4981957Sbrian * signal. 5081957Sbrian */ 5128679Sbrianstatic void 5228679Sbriansignal_recorder(int sig) 5328679Sbrian{ 5428679Sbrian caused[sig - 1]++; 5545126Sbrian necessary = 1; 5623840Sbrian} 5723840Sbrian 5823840Sbrian 5923840Sbrian/* 6081957Sbrian * Set up signal_recorder to handle the given sig and record ``fn'' as 6181957Sbrian * the function to ultimately call in sig_Handle(). ``fn'' will not be 6281957Sbrian * called in signal context (as sig_Handle() is not called in signal 6381957Sbrian * context). 6481957Sbrian */ 6528679Sbriansig_type 6636285Sbriansig_signal(int sig, sig_type fn) 6728679Sbrian{ 6828679Sbrian sig_type Result; 6923840Sbrian 7028679Sbrian if (sig <= 0 || sig > NSIG) { 7128679Sbrian /* Oops - we must be a bit out of date (too many sigs ?) */ 7236285Sbrian log_Printf(LogALERT, "Eeek! %s:%d: I must be out of date!\n", 7328679Sbrian __FILE__, __LINE__); 7428679Sbrian return signal(sig, fn); 7528679Sbrian } 7628679Sbrian Result = handler[sig - 1]; 7728679Sbrian if (fn == SIG_DFL || fn == SIG_IGN) { 7828679Sbrian signal(sig, fn); 7928679Sbrian handler[sig - 1] = (sig_type) 0; 8028679Sbrian } else { 8128679Sbrian handler[sig - 1] = fn; 8228679Sbrian signal(sig, signal_recorder); 8328679Sbrian } 8428679Sbrian caused[sig - 1] = 0; 8528679Sbrian return Result; 8623840Sbrian} 8723840Sbrian 8823840Sbrian 8981957Sbrian/* 9081957Sbrian * Call the handlers for any pending signals 9181957Sbrian * 9281957Sbrian * This function is called from a non-signal context - in fact, it's 9381957Sbrian * called every time select() in DoLoop() returns - just in case 9481957Sbrian * select() returned due to a signal being recorded by signal_recorder(). 9581957Sbrian */ 9645126Sbrianint 9736285Sbriansig_Handle() 9828679Sbrian{ 9928679Sbrian int sig; 10028679Sbrian int got; 10145126Sbrian int result; 10223840Sbrian 10345126Sbrian result = 0; 10445126Sbrian if (necessary) { 10545126Sbrian /* We've *probably* got something in `caused' set */ 10645126Sbrian necessary = 0; 10745126Sbrian /* `necessary' might go back to 1 while we're in here.... */ 10845126Sbrian do { 10945126Sbrian got = 0; 11045126Sbrian for (sig = 0; sig < NSIG; sig++) 11145126Sbrian if (caused[sig]) { 11245126Sbrian caused[sig]--; 11345126Sbrian got++; 11445126Sbrian result++; 11545126Sbrian (*handler[sig])(sig + 1); 11645126Sbrian } 11745126Sbrian } while (got); 11845126Sbrian } 11945126Sbrian 12045126Sbrian return result; 12123840Sbrian} 122