#if __DARWIN_UNIX03
#ifdef VARIANT_CANCELABLE
#include <pthread.h>
#endif
extern int __unix_conforming;
#endif
#include <sys/param.h>
#include <signal.h>
#include <errno.h>
#ifndef BUILDING_VARIANT
#if defined(__DYNAMIC__)
extern int _sigaction_nobind (int sig, const struct sigaction *nsv, struct sigaction *osv);
extern int _sigvec_nobind (int, struct sigvec *, struct sigvec *);
#endif
static int
sigvec__(int signo,
struct sigvec *sv,
struct sigvec *osv,
int bind)
{
int ret;
if (sv)
sv->sv_flags ^= SV_INTERRUPT;
#if defined(__DYNAMIC__)
if (bind) {
#endif
ret = sigaction(signo, (struct sigaction *)sv, (struct sigaction *)osv);
#if defined(__DYNAMIC__)
} else {
ret = _sigaction_nobind(signo, (struct sigaction *)sv, (struct sigaction *)osv);
}
#endif
if (ret == 0 && osv)
osv->sv_flags ^= SV_INTERRUPT;
return (ret);
}
int
sigvec(int signo,
struct sigvec *sv,
struct sigvec *osv)
{
return sigvec__(signo, sv, osv, 1);
}
#if defined(__DYNAMIC__)
int
_sigvec_nobind(int signo,
struct sigvec *sv,
struct sigvec *osv)
{
return sigvec__(signo, sv, osv, 0);
}
#endif
int
sigsetmask(int mask)
{
int omask, n;
n = sigprocmask(SIG_SETMASK, (sigset_t *) &mask, (sigset_t *) &omask);
if (n)
return (n);
return (omask);
}
int
sigblock(int mask)
{
int omask, n;
n = sigprocmask(SIG_BLOCK, (sigset_t *) &mask, (sigset_t *) &omask);
if (n)
return (n);
return (omask);
}
#endif
#if __DARWIN_UNIX03
int
sigpause(int sig)
{
sigset_t mask;
if (__unix_conforming == 0)
__unix_conforming = 1;
#ifdef VARIANT_CANCELABLE
pthread_testcancel();
#endif
if ((sig <= 0) || (sig >= NSIG)) {
errno = EINVAL;
return(-1);
}
if (sigprocmask(SIG_BLOCK, (sigset_t *) 0, (sigset_t *) &mask) < 0) {
return(-1);
}
sigdelset(&mask, sig);
return (sigsuspend(&mask));
}
#else
int
sigpause(int mask)
{
return (sigsuspend((sigset_t *)&mask));
}
#endif
#ifndef BUILDING_VARIANT
int
sighold(int sig)
{
sigset_t mask;
if ((sig <= 0) || (sig >= NSIG)) {
errno = EINVAL;
return(-1);
}
sigemptyset(&mask);
sigaddset(&mask, sig);
return(sigprocmask(SIG_BLOCK, &mask,(sigset_t *)0));
}
int
sigrelse(int sig)
{
sigset_t mask;
if ((sig <= 0) || (sig >= NSIG)) {
errno = EINVAL;
return(-1);
}
sigemptyset(&mask);
sigaddset(&mask, sig);
return(sigprocmask(SIG_UNBLOCK, &mask,(sigset_t *)0));
}
int
sigignore(int sig)
{
return (signal(sig, SIG_IGN) == SIG_ERR ? -1 : 0);
}
void (*sigset(int sig, void (*disp)(int)))(int) {
sigset_t omask;
int blocked;
struct sigaction oact;
if ((sig <= 0) || (sig >= NSIG)) {
errno = EINVAL;
return (SIG_ERR);
}
if (-1 == sigprocmask(0, NULL, &omask))
return (SIG_ERR);
blocked = sigismember(&omask, sig);
if (disp == SIG_HOLD) {
if (blocked)
return (SIG_HOLD);
if ((-1 == sigaction(sig, NULL, &oact)) ||
(-1 == sighold(sig)))
return (SIG_ERR);
return (sig_t)oact.sa_handler;
} else {
if (blocked) {
if (-1 == sigrelse(sig))
return (SIG_ERR);
}
sig_t rv = signal(sig, disp);
if (rv != SIG_ERR)
return blocked ? SIG_HOLD : rv;
else
return (rv);
}
}
#endif