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