#include "sh.h"
RCSID("$Id: tc.sig.c,v 3.29 2005/01/18 20:24:51 christos Exp $")
#include "tc.wait.h"
#ifndef BSDSIGS
#define MAX_CHLD 50
# ifdef UNRELSIGS
static struct mysigstack {
int s_w;
int s_errno;
pid_t s_pid;
} stk[MAX_CHLD];
static int stk_ptr = -1;
static RETSIGTYPE
sig_ch_queue()
{
# ifdef JOBDEBUG
xprintf("queue SIGCHLD\n");
flush();
# endif
stk_ptr++;
stk[stk_ptr].s_pid = (pid_t) wait(&stk[stk_ptr].s_w);
stk[stk_ptr].s_errno = errno;
(void) signal(SIGCHLD, sig_ch_queue);
}
static RETSIGTYPE
sig_ch_rel()
{
while (stk_ptr > -1)
pchild(SIGCHLD);
# ifdef JOBDEBUG
xprintf("signal(SIGCHLD, pchild);\n");
# endif
(void) signal(SIGCHLD, pchild);
}
RETSIGTYPE
(*xsigset(a, b)) ()
int a;
signalfun_t b;
{
return (signal(a, b));
}
void
sigrelse(what)
int what;
{
if (what == SIGCHLD)
sig_ch_rel();
# ifdef COHERENT
(void) signal(what, what == SIGINT ? pintr : SIG_DFL);
# endif
}
void
xsighold(what)
int what;
{
if (what == SIGCHLD)
(void) signal(SIGCHLD, sig_ch_queue);
# ifdef COHERENT
(void) signal(what, SIG_IGN);
# endif
}
void
xsigignore(a)
int a;
{
(void) signal(a, SIG_IGN);
}
void
xsigpause(what)
int what;
{
if (what == SIGCHLD)
pchild(SIGCHLD);
}
pid_t
ourwait(w)
int *w;
{
pid_t pid;
# ifdef JOBDEBUG
xprintf(CGETS(25, 1, "our wait %d\n"), stk_ptr);
flush();
# endif
if (stk_ptr == -1) {
pid = (pid_t) wait(w);
# ifdef JOBDEBUG
xprintf("signal(SIGCHLD, pchild);\n");
# endif
(void) signal(SIGCHLD, pchild);
return (pid);
}
else {
errno = stk[stk_ptr].s_errno;
*w = stk[stk_ptr].s_w;
stk_ptr--;
return (stk[stk_ptr + 1].s_pid);
}
}
# ifdef COHERENT
# undef signal
RETSIGTYPE
(*xsignal(a, b)) ()
int a;
signalfun_t b;
{
if (a == SIGCHLD)
return SIG_DFL;
else
return (signal(a, b));
}
# endif
# endif
# ifdef SXA
void
sigpause(what)
{
if (what == SIGCHLD) {
(void) bsd_sigpause(bsd_sigblock((sigmask_t) 0) & ~sigmask(SIGBSDCHLD));
}
else if (what == 0) {
pause();
}
else {
xprintf("sigpause(%d)\n", what);
pause();
}
}
# endif
#endif
#ifdef NEEDsignal
RETSIGTYPE
(*xsignal(s, a)) ()
int s;
signalfun_t a;
{
sigvec_t osv, sv;
(void) mysigvec(s, NULL, &osv);
sv = osv;
sv.sv_handler = a;
#ifdef SIG_STK
sv.sv_onstack = SIG_STK;
#endif
#ifdef SV_BSDSIG
sv.sv_flags = SV_BSDSIG;
#endif
if (mysigvec(s, &sv, NULL) < 0)
return (BADSIG);
return (osv.sv_handler);
}
#endif
#ifdef POSIXSIGS
extern int errno;
#define SETBIT(x, y) x |= sigmask(y)
#define ISSET(x, y) ((x & sigmask(y)) != 0)
#ifdef DEBUG
# define SHOW_SIGNALS 1
#endif
#ifdef SHOW_SIGNALS
char *show_sig_mask();
#endif
#ifndef __PARAGON__
sigmask_t
sigsetmask(mask)
sigmask_t mask;
{
sigset_t set, oset;
int m;
int i;
(void) sigemptyset(&set);
(void) sigemptyset(&oset);
for (i = 1; i <= MAXSIG; i++)
if (ISSET(mask, i))
(void) sigaddset(&set, i);
if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1) {
xprintf("sigsetmask(0x%x) - sigprocmask failed, errno %d",
mask, errno);
}
m = 0;
for (i = 1; i <= MAXSIG; i++)
if (sigismember(&oset, i) == 1)
SETBIT(m, i);
return (m);
}
#endif
#ifndef __DGUX__
sigmask_t
sigblock(mask)
sigmask_t mask;
{
sigset_t set, oset;
int m;
int i;
(void) sigemptyset(&set);
(void) sigemptyset(&oset);
if ((sigprocmask(SIG_SETMASK, NULL, &set)) == -1)
stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
for (i = 1; i <= MAXSIG; i++)
if (ISSET(mask, i))
(void) sigaddset(&set, i);
if ((sigprocmask(SIG_SETMASK, &set, &oset)) == -1)
stderror(ERR_SYSTEM, "sigprocmask", strerror(errno));
m = 0;
for (i = 1; i <= MAXSIG; i++)
if (sigismember(&oset, i) == 1)
SETBIT(m, i);
return (m);
}
#endif
void
bsd_sigpause(mask)
sigmask_t mask;
{
sigset_t set;
int i;
(void) sigemptyset(&set);
for (i = 1; i <= MAXSIG; i++)
if (ISSET(mask, i))
(void) sigaddset(&set, i);
(void) sigsuspend(&set);
}
RETSIGTYPE (*bsd_signal(sig, func)) ()
int sig;
signalfun_t func;
{
struct sigaction act, oact;
sigset_t set;
signalfun_t r_func;
if (sig < 0 || sig > MAXSIG) {
xprintf(CGETS(25, 2,
"error: bsd_signal(%d) signal out of range\n"), sig);
return((signalfun_t) SIG_IGN);
}
(void) sigemptyset(&set);
act.sa_handler = (signalfun_t) func;
act.sa_mask = set;
act.sa_flags = 0;
if (sigaction(sig, &act, &oact)) {
xprintf(CGETS(25, 3,
"error: bsd_signal(%d) - sigaction failed, errno %d\n"),
sig, errno);
return((signalfun_t) SIG_IGN);
}
r_func = (signalfun_t) oact.sa_handler;
return(r_func);
}
#endif
#ifdef SIGSYNCH
static long Synch_Cnt = 0;
RETSIGTYPE
synch_handler(sno)
int sno;
{
if (sno != SIGSYNCH)
abort();
Synch_Cnt++;
}
#endif