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