diff options
Diffstat (limited to 'gnu/usr.bin/cvs/lib/sighandle.c')
-rw-r--r-- | gnu/usr.bin/cvs/lib/sighandle.c | 405 |
1 files changed, 0 insertions, 405 deletions
diff --git a/gnu/usr.bin/cvs/lib/sighandle.c b/gnu/usr.bin/cvs/lib/sighandle.c deleted file mode 100644 index a225983..0000000 --- a/gnu/usr.bin/cvs/lib/sighandle.c +++ /dev/null @@ -1,405 +0,0 @@ -/* sighandle.c -- Library routines for manipulating chains of signal handlers - Copyright (C) 1992 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Written by Paul Sander, HaL Computer Systems, Inc. <paul@hal.com> - Brian Berliner <berliner@Sun.COM> added POSIX support */ - -/************************************************************************* - * - * signal.c -- This file contains code that manipulates chains of signal - * handlers. - * - * Facilities are provided to register a signal handler for - * any specific signal. When a signal is received, all of the - * registered signal handlers are invoked in the reverse order - * in which they are registered. Note that the signal handlers - * must not themselves make calls to the signal handling - * facilities. - * - * $CVSid: @(#)sighandle.c 1.13 94/10/07 $ - * - *************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "system.h" - -#include <sys/types.h> -#include <stdio.h> -#include <signal.h> - -#ifdef STDC_HEADERS -#include <stdlib.h> -#else -#if __STDC__ -char *calloc(unsigned nelem, unsigned size); -char *malloc(unsigned size); -#else -char *calloc(); -char *malloc(); -#endif /* __STDC__ */ -#endif /* STDC_HEADERS */ - -/* Define the highest signal number (usually) */ -#ifndef SIGMAX -#define SIGMAX 64 -#endif - -/* Define linked list of signal handlers structure */ -struct SIG_hlist { - RETSIGTYPE (*handler)(); - struct SIG_hlist *next; -}; - -/* - * Define array of lists of signal handlers. Note that this depends on - * the implementation to initialize each element to a null pointer. - */ - -static struct SIG_hlist **SIG_handlers; - -/* Define array of default signal vectors */ - -#ifdef POSIX_SIGNALS -static struct sigaction *SIG_defaults; -#else -#ifdef BSD_SIGNALS -static struct sigvec *SIG_defaults; -#else -static RETSIGTYPE (**SIG_defaults)(); -#endif -#endif - -/* Critical section housekeeping */ -static int SIG_crSectNest = 0; /* Nesting level */ -#ifdef POSIX_SIGNALS -static sigset_t SIG_crSectMask; /* Signal mask */ -#else -static int SIG_crSectMask; /* Signal mask */ -#endif - -/* - * Initialize the signal handler arrays - */ - -static int SIG_init() -{ - int i; -#ifdef POSIX_SIGNALS - sigset_t sigset_test; -#endif - - if (SIG_defaults && SIG_handlers) /* already allocated */ - return (0); - -#ifdef POSIX_SIGNALS - (void) sigfillset(&sigset_test); - for (i = 1; i < SIGMAX && sigismember(&sigset_test, i) == 1; i++) - ; - if (i < SIGMAX) - i = SIGMAX; - i++; - if (!SIG_defaults) - SIG_defaults = (struct sigaction *) - calloc(i, sizeof(struct sigaction)); - (void) sigemptyset(&SIG_crSectMask); -#else - i = SIGMAX+1; -#ifdef BSD_SIGNALS - if (!SIG_defaults) - SIG_defaults = (struct sigvec *) - calloc(i, sizeof(struct sigvec)); -#else - if (!SIG_defaults) - SIG_defaults = (RETSIGTYPE (**)()) - calloc(i, sizeof(RETSIGTYPE (**)())); -#endif - SIG_crSectMask = 0; -#endif - if (!SIG_handlers) - SIG_handlers = (struct SIG_hlist **) - calloc(i, sizeof(struct SIG_hlist *)); - return (!SIG_defaults || !SIG_handlers); -} - -/* - * The following invokes each signal handler in the reverse order in which - * they were registered. - */ - -static RETSIGTYPE SIG_handle(sig) -int sig; -{ - struct SIG_hlist *this; - - /* Dispatch signal handlers */ - this = SIG_handlers[sig]; - while (this != (struct SIG_hlist *) NULL) - { - (*this->handler)(sig); - this = this->next; - } - - return; -} - -/* - * The following registers a signal handler. If the handler is already - * registered, it is not registered twice, nor is the order in which signal - * handlers are invoked changed. If this is the first signal handler - * registered for a given signal, the old sigvec structure is saved for - * restoration later. - */ - -int SIG_register(sig,fn) -int sig; -RETSIGTYPE (*fn)(); -{ - int val; - struct SIG_hlist *this; -#ifdef POSIX_SIGNALS - struct sigaction act; - sigset_t sigset_mask, sigset_omask; -#else -#ifdef BSD_SIGNALS - struct sigvec vec; - int mask; -#endif -#endif - - /* Initialize */ - if (SIG_init() != 0) - return (-1); - val = 0; - - /* Block this signal while we look at handler chain */ -#ifdef POSIX_SIGNALS - (void) sigemptyset(&sigset_mask); - (void) sigaddset(&sigset_mask, sig); - (void) sigprocmask(SIG_BLOCK, &sigset_mask, &sigset_omask); -#else -#ifdef BSD_SIGNALS - mask = sigblock(sigmask(sig)); -#endif -#endif - - /* See if this handler was already registered */ - this = SIG_handlers[sig]; - while (this != (struct SIG_hlist *) NULL) - { - if (this->handler == fn) break; - this = this->next; - } - - /* Register the new handler only if it is not already registered. */ - if (this == (struct SIG_hlist *) NULL) - { - - /* - * If this is the first handler registered for this signal, - * set up the signal handler dispatcher - */ - - if (SIG_handlers[sig] == (struct SIG_hlist *) NULL) - { -#ifdef POSIX_SIGNALS - act.sa_handler = SIG_handle; - (void) sigemptyset(&act.sa_mask); - act.sa_flags = 0; - val = sigaction(sig, &act, &SIG_defaults[sig]); -#else -#ifdef BSD_SIGNALS - bzero((char *)&vec, sizeof(vec)); - vec.sv_handler = SIG_handle; - val = sigvec(sig, &vec, &SIG_defaults[sig]); -#else - if ((SIG_defaults[sig] = signal(sig, SIG_handle)) == - (RETSIGTYPE (*)()) -1) - val = -1; -#endif -#endif - } - - /* If not, register it */ - if ((val == 0) && (this == (struct SIG_hlist *) NULL)) - { - this = (struct SIG_hlist *) - malloc(sizeof(struct SIG_hlist)); - if (this == NULL) - { - val = -1; - } - else - { - this->handler = fn; - this->next = SIG_handlers[sig]; - SIG_handlers[sig] = this; - } - } - } - - /* Unblock the signal */ -#ifdef POSIX_SIGNALS - (void) sigprocmask(SIG_SETMASK, &sigset_omask, NULL); -#else -#ifdef BSD_SIGNALS - (void) sigsetmask(mask); -#endif -#endif - - return val; -} - -/* - * The following deregisters a signal handler. If the last signal handler for - * a given signal is deregistered, the default sigvec information is restored. - */ - -int SIG_deregister(sig,fn) -int sig; -RETSIGTYPE (*fn)(); -{ - int val; - struct SIG_hlist *this; - struct SIG_hlist *last; -#ifdef POSIX_SIGNALS - sigset_t sigset_mask, sigset_omask; -#else -#ifdef BSD_SIGNALS - int mask; -#endif -#endif - - /* Initialize */ - if (SIG_init() != 0) - return (-1); - val = 0; - last = (struct SIG_hlist *) NULL; - - /* Block this signal while we look at handler chain */ -#ifdef POSIX_SIGNALS - (void) sigemptyset(&sigset_mask); - (void) sigaddset(&sigset_mask, sig); - (void) sigprocmask(SIG_BLOCK, &sigset_mask, &sigset_omask); -#else -#ifdef BSD_SIGNALS - mask = sigblock(sigmask(sig)); -#endif -#endif - - /* Search for the signal handler */ - this = SIG_handlers[sig]; - while ((this != (struct SIG_hlist *) NULL) && (this->handler != fn)) - { - last = this; - this = this->next; - } - - /* If it was registered, remove it */ - if (this != (struct SIG_hlist *) NULL) - { - if (last == (struct SIG_hlist *) NULL) - { - SIG_handlers[sig] = this->next; - } - else - { - last->next = this->next; - } - free((char *) this); - } - - /* Restore default behavior if there are no registered handlers */ - if (SIG_handlers[sig] == (struct SIG_hlist *) NULL) - { -#ifdef POSIX_SIGNALS - val = sigaction(sig, &SIG_defaults[sig], - (struct sigaction *) NULL); -#else -#ifdef BSD_SIGNALS - val = sigvec(sig, &SIG_defaults[sig], (struct sigvec *) NULL); -#else - if (signal(sig, SIG_defaults[sig]) == (RETSIGTYPE (*)()) -1) - val = -1; -#endif -#endif - } - - /* Unblock the signal */ -#ifdef POSIX_SIGNALS - (void) sigprocmask(SIG_SETMASK, &sigset_omask, NULL); -#else -#ifdef BSD_SIGNALS - (void) sigsetmask(mask); -#endif -#endif - - return val; -} - -/* - * The following begins a critical section. - */ - -void SIG_beginCrSect() -{ - if (SIG_init() == 0) - { - if (SIG_crSectNest == 0) - { -#ifdef POSIX_SIGNALS - sigset_t sigset_mask; - - (void) sigfillset(&sigset_mask); - (void) sigprocmask(SIG_SETMASK, - &sigset_mask, &SIG_crSectMask); -#else -#ifdef BSD_SIGNALS - SIG_crSectMask = sigblock(~0); -#else - /* TBD */ -#endif -#endif - } - SIG_crSectNest++; - } -} - -/* - * The following ends a critical section. - */ - -void SIG_endCrSect() -{ - if (SIG_init() == 0) - { - SIG_crSectNest--; - if (SIG_crSectNest == 0) - { -#ifdef POSIX_SIGNALS - (void) sigprocmask(SIG_SETMASK, &SIG_crSectMask, NULL); -#else -#ifdef BSD_SIGNALS - (void) sigsetmask(SIG_crSectMask); -#else - /* TBD */ -#endif -#endif - } - } -} |