sig.c revision 23840
123840Sbrian/*-
223840Sbrian * Copyright (c) 1997
323840Sbrian *	Brian Somers <brian@awfulhak.demon.co.uk>.  All rights reserved.
423840Sbrian *
523840Sbrian * Redistribution and use in source and binary forms, with or without
623840Sbrian * modification, are permitted provided that the following conditions
723840Sbrian * are met:
823840Sbrian * 1. Redistributions of source code must retain the above copyright
923840Sbrian *    notice, this list of conditions and the following disclaimer.
1023840Sbrian * 2. Redistributions in binary form must reproduce the above copyright
1123840Sbrian *    notice, this list of conditions and the following disclaimer in the
1223840Sbrian *    documentation and/or other materials provided with the distribution.
1323840Sbrian * 3. Neither the name of the University nor the names of its contributors
1423840Sbrian *    may be used to endorse or promote products derived from this software
1523840Sbrian *    without specific prior written permission.
1623840Sbrian *
1723840Sbrian * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
1823840Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1923840Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2023840Sbrian * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2123840Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2223840Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2323840Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2423840Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2523840Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2623840Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2723840Sbrian * SUCH DAMAGE.
2823840Sbrian *
2923840Sbrian * $Id: sig.c,v 1.4 1997/02/25 14:05:10 brian Exp $
3023840Sbrian *
3123840Sbrian *  TODO:
3223840Sbrian *
3323840Sbrian */
3423840Sbrian
3523840Sbrian#include <sys/cdefs.h>
3623840Sbrian#include "sig.h"
3723840Sbrian#include <sys/types.h>
3823840Sbrian#include <signal.h>
3923840Sbrian#include "mbuf.h"
4023840Sbrian#include "log.h"
4123840Sbrian
4223840Sbrianstatic caused[NSIG];		/* An array of pending signals */
4323840Sbrianstatic sig_type handler[NSIG];	/* all start at SIG_DFL */
4423840Sbrian
4523840Sbrian
4623840Sbrian/* Record a signal in the "caused" array */
4723840Sbrian
4823840Sbrianstatic void signal_recorder(int sig) {
4923840Sbrian        caused[sig-1]++;
5023840Sbrian}
5123840Sbrian
5223840Sbrian
5323840Sbrian/*
5423840Sbrian    set up signal_recorder, and record handler as the function to ultimately
5523840Sbrian    call in handle_signal()
5623840Sbrian*/
5723840Sbrian
5823840Sbriansig_type pending_signal(int sig,sig_type fn) {
5923840Sbrian    sig_type Result;
6023840Sbrian
6123840Sbrian    if (sig <= 0 || sig > NSIG) {
6223840Sbrian	/* Oops - we must be a bit out of date (too many sigs ?) */
6323840Sbrian        logprintf("Eeek! %s:%s: I must be out of date!\n",__FILE__,__LINE__);
6423840Sbrian        return signal(sig,fn);
6523840Sbrian    }
6623840Sbrian
6723840Sbrian    Result = handler[sig-1];
6823840Sbrian    if (fn == SIG_DFL || fn == SIG_IGN) {
6923840Sbrian        signal(sig,fn);
7023840Sbrian        handler[sig-1] = (sig_type)0;
7123840Sbrian    } else {
7223840Sbrian        handler[sig-1] = fn;
7323840Sbrian        signal(sig,signal_recorder);
7423840Sbrian    }
7523840Sbrian    caused[sig-1] = 0;
7623840Sbrian    return Result;
7723840Sbrian}
7823840Sbrian
7923840Sbrian
8023840Sbrian/* Call the handlers for any pending signals */
8123840Sbrian
8223840Sbrianvoid handle_signals() {
8323840Sbrian    int sig;
8423840Sbrian    int got;
8523840Sbrian
8623840Sbrian    do {
8723840Sbrian       got = 0;
8823840Sbrian       for (sig = 0; sig < NSIG; sig++)
8923840Sbrian           if (caused[sig]) {
9023840Sbrian               caused[sig]--;
9123840Sbrian               got++;
9223840Sbrian               (*handler[sig])(sig+1);
9323840Sbrian           }
9423840Sbrian    } while(got);
9523840Sbrian}
96