/* * Copyright (c) 2001-2005 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Sponsored in part by the Defense Advanced Research Projects * Agency (DARPA) and Air Force Research Laboratory, Air Force * Materiel Command, USAF, under agreement number F39502-99-1-0512. */ #include #include #include #ifndef lint __unused static const char rcsid[] = "$Sudo: sigaction.c,v 1.5.2.2 2007/06/12 01:28:42 millert Exp $"; #endif /* lint */ int sigaction(signo, sa, osa) int signo; const sigaction_t *sa; sigaction_t *osa; { sigaction_t nsa; int error; /* We must reverse SV_INTERRUPT since it is the opposite of SA_RESTART */ if (sa) { nsa = *sa; nsa.sa_flags ^= SV_INTERRUPT; sa = &nsa; } error = sigvec(signo, sa, osa); if (!error && osa) osa->sa_flags ^= SV_INTERRUPT; /* flip SV_INTERRUPT as above */ return(error); } int sigemptyset(set) sigset_t *set; { *set = 0; return(0); } int sigfillset(set) sigset_t *set; { *set = ~0;; return(0); } int sigaddset(set, signo) sigset_t *set; int signo; { if (signo <= 0 || signo >= NSIG) { errno = EINVAL; return(-1); } SET(*set, sigmask(signo)); return(0); } int sigdelset(set, signo) sigset_t *set; int signo; { if (signo <= 0 || signo >= NSIG) { errno = EINVAL; return(-1); } CLR(*set, sigmask(signo)); return(0); } int sigismember(set, signo) sigset_t *set; int signo; { return(ISSET(*set, sigmask(signo))); } int sigprocmask(how, set, oset) int how; const sigset_t *set; sigset_t *oset; { int mask; /* If 'set' is NULL the user just wants the current signal mask. */ if (set == 0) mask = sigblock(0); else switch (how) { case SIG_BLOCK: mask = sigblock(*set); break; case SIG_UNBLOCK: mask = sigsetmask(~*set); break; case SIG_SETMASK: mask = sigsetmask(*set); break; default: return(-1); } if (mask == -1) return(-1); if (oset) *oset = mask; return(0); }