Coherent4.2.10/coh.386/lib/proc_ssig.c

Compare this file to the similar file:
Show the results in this format:

/* $Header: /ker/coh.386/RCS/ker_data.c,v 2.4 93/08/19 03:26:31 nigel Exp Locker: nigel $ */
/*
 * This file contains definitions for the functions which support the Coherent
 * internal binary-compatibility scheme. We select _SYSV3 to get some old
 * definitions like makedev () visible.
 *
 * $Log:	ker_data.c,v $
 * Revision 2.4  93/08/19  03:26:31  nigel
 * Nigel's r83 (Stylistic cleanup)
 * 
 * Revision 2.2  93/07/26  14:55:28  nigel
 * Nigel's R80
 */

#define	_SYSV3		1
#define	_DDI_DKI	1
#define	_DDI_DKI_IMPL	1

#include <common/ccompat.h>
#include <kernel/sig_lib.h>
#include <kernel/proc_lib.h>
#include <sys/debug.h>
#include <sys/types.h>
#include <string.h>

/*
 * These two pull in all the old-style trash.
 */

#define	_KERNEL	1

#include <sys/uproc.h>
#include <sys/proc.h>


#if	_SIGNAL_MAX <= __LONG_BIT
/*
 * For optimizing handling of job-control signals.
 */

#define	STOP_SIGNALS	(__SIGSET_MASK (SIGSTOP) | __SIGSET_MASK (SIGTSTP) |\
			 __SIGSET_MASK (SIGTTIN) | __SIGSET_MASK (SIGTTOU))
#endif

/*
 * Add the given signal to the indicated process's pending-signal mask and if
 * the process requires some notification (such as being woken if asleep, or
 * interrupted if scheduled on another processor) then perform that.
 *
 * This function can only be called from base level, but we must be aware of
 * the fact that process state-changes can happen at interrupt level and that
 * we can be interacting with multiple processors.
 */

#if	__USE_PROTO__
void proc_send_signal (__proc_t * process, __CONST__ __siginfo_t * siginfo)
#else
void
proc_send_signal (process, siginfo)
__proc_t      *	process;
__CONST__ __siginfo_t
	      *	siginfo;
#endif
{
	__sigmask_t	mask;
	pl_t		prev_pl;

	ASSERT (process != NULL && siginfo != NULL);
	ASSERT (siginfo->__si_signo > 0 && siginfo->__si_signo <= _SIGNAL_MAX);

	mask = __SIGSET_MASK (siginfo->__si_signo);

	if (siginfo->__si_signo == SIGCONT) {
		/*
		 * When a SIGCONT is received, all pending stop signals are
		 * discarded and if the process is stopped, it is continued.
		 */

#if	_SIGNAL_MAX <= __LONG_BIT
		__SIGSET_CLRMASK (process->p_pending_signals, 0,
				  STOP_SIGNALS);
#else
		__SIGSET_CLRBIT (process->p_pending_signals, SIGSTOP);
		__SIGSET_CLRBIT (process->p_pending_signals, SIGTSTP);
		__SIGSET_CLRBIT (process->p_pending_signals, SIGTTIN);
		__SIGSET_CLRBIT (process->p_pending_signals, SIGTTOU);
#endif

#ifdef	PROC_IS_STOPPED
		if (PROC_IS_STOPPED (process))
			PROC_CONTINUE (process);
#endif
	}

#if	_SIGNAL_MAX <= __LONG_BIT
	if ((mask & STOP_SIGNALS) != 0) {
#else
	if (siginfo->__si_signo == SIGSTOP ||
	    siginfo->__si_signo == SIGTSTP ||
	    siginfo->__si_signo == SIGTTIN ||
	    siginfo->__si_signo == SIGTTOU) {
#endif
		/*
		 * When a stop signal is received, any pending SIGCONT signal
		 * is discarded.
		 */

		__SIGSET_CLRBIT (process->p_pending_signals, SIGCONT);
	}


#if	0
	if (__SIGSET_TSTMASK (process->p_queued_signals, siginfo->__si_signo,
			      mask) != 0) {
		/*
		 * Reliable signal-queueing is in effect, so we must stash
		 * away a copy of the structure pointed at by "siginfo" so we
		 * can deliver the information as an additional argument to
		 * the signal-catching function.
		 */
		ASSERT ("Not implemented" == NULL);
	}
#endif	/* NOT IMPLEMENTED */


	/*
	 * Here we are about to modify some shared per-process state; now is a
	 * good time to take a lock, so we structure the code so it can be
	 * released. We require a basic lock for the state-change code, so we
	 * use that lock to cover the process-level guard as well. In a uni-
	 * processor system, the process-level guard is not necessary, but the
	 * extra area covered is small enough that it doesn't matter.
	 */

	prev_pl = PROC_STATE_LOCK (process);

	__SIGSET_ADDMASK (process->p_pending_signals,
			  siginfo->__si_signo, mask);

	if (! __SIGSET_TSTMASK (process->p_signal_mask,
				siginfo->__si_signo, mask) &&
	    ! __SIGSET_TSTMASK (process->p_ignored_signals,
				siginfo->__si_signo, mask) &&
	    process->p_state == PSSLSIG) {
		/*
		 * The process is sleeping and wants to be woken by
		 * signals, arrange for it to come out of sleep so it
		 * can get to user-level and process the signal.
		 */

		process_wake_signal (process);
	}

	PROC_STATE_UNLOCK (process, prev_pl);
}