/* sigactio.c (rsxnt) -- Copyright (c) 1996-1997 Rainer Schnitker */

#include "rsxnt.h"

static void check_pending(EMXPROCESS *proc, int signum)
{
    struct sigaction *p;

    p = signum - 1 + proc->sigaction;
    if (p->sa_handler == SIG_IGN) {
	if (signum == SIGCHLD)
	    return;
	proc->sig_raised &= ~ SIGMASK(signum);
	    return;
    }
    if (p->sa_handler == SIG_DFL) {
	if (signum != SIGCHLD)
	    return;
	proc->sig_raised &= ~ SIGMASK(signum);
	return;
    }
}

int __sigaction (int signum, const struct sigaction *action,
		struct sigaction *oldaction)
{
    EMXPROCESS *proc = _rsxnt_get_process_ptr();
    struct sigaction new_sa, *p;

    if (signum < 1 || signum >= NSIG || signum==SIGKILL)
	return _rsxnt_errno(EINVAL);
    p = signum - 1 + proc->sigaction;
    if (action) {
	memcpy(&new_sa, action, sizeof(struct sigaction));
	new_sa.sa_mask |= SIGMASK(signum);
	new_sa.sa_mask &= SIGBLOCK;
    }
    if (oldaction)
	memcpy(oldaction, p, sizeof(struct sigaction));
    if (action) {
	*p = new_sa;
	check_pending(proc, signum);
    }
#ifdef EMX_SYS_LIB
	_rsxnt_check_signals();
#endif
    return 0;
}
