Esempio n. 1
0
int
smb_proc_intr(struct proc *p)
{
	sigset_t tmpset;

	if (p == NULL)
		return 0;
	tmpset = p->p_siglist;
	SIGSETNAND(tmpset, p->p_sigmask);
	SIGSETNAND(tmpset, p->p_sigignore);
	if (SIGNOTEMPTY(p->p_siglist) && SMB_SIGMASK(tmpset))
                return EINTR;
	return 0;
}
Esempio n. 2
0
int
smb_proc_intr(struct thread *td)
{
	sigset_t tmpset;
	struct proc *p;
	struct lwp *lp;

	if (td == NULL || (p = td->td_proc) == NULL)
		return 0;
	lp = td->td_lwp;
	tmpset = lwp_sigpend(lp);
	SIGSETNAND(tmpset, lp->lwp_sigmask);
	SIGSETNAND(tmpset, p->p_sigignore);
	if (SIGNOTEMPTY(tmpset) && SMB_SIGMASK(tmpset))
                return EINTR;
	return 0;
}
Esempio n. 3
0
int
_sigsuspend(const sigset_t *set)
{
	struct pthread	*curthread = _get_curthread();
	sigset_t	oldmask, newmask, tempset;
	int             ret = -1;

	if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)
		return (__sys_sigsuspend(set));

	/* Check if a new signal set was provided by the caller: */
	if (set != NULL) {
		newmask = *set;
		SIG_CANTMASK(newmask);
		THR_LOCK_SWITCH(curthread);

		/* Save current sigmask: */
		oldmask = curthread->sigmask;
		curthread->oldsigmask = &oldmask;

		/* Change the caller's mask: */
		curthread->sigmask = newmask;
		tempset = curthread->sigpend;
		SIGSETNAND(tempset, newmask);
		if (SIGISEMPTY(tempset)) {
			THR_SET_STATE(curthread, PS_SIGSUSPEND);
			/* Wait for a signal: */
			_thr_sched_switch_unlocked(curthread);
		} else {
			curthread->check_pending = 1;
			THR_UNLOCK_SWITCH(curthread);
			/* check pending signal I can handle: */
			_thr_sig_check_pending(curthread);
		}
		if ((curthread->cancelflags & THR_CANCELLING) != 0)
			curthread->oldsigmask = NULL;
		else {
			THR_ASSERT(curthread->oldsigmask == NULL,
		 	          "oldsigmask is not cleared");
		}

		/* Always return an interrupted error: */
		errno = EINTR;
	} else {
		/* Return an invalid argument error: */
		errno = EINVAL;
	}

	/* Return the completion status: */
	return (ret);
}
Esempio n. 4
0
int
ncp_chkintr(struct ncp_conn *conn, struct thread *td)
{
	struct proc *p;
	sigset_t tmpset;

	if (td == NULL)
		return 0;
	p = td->td_proc;
	PROC_LOCK(p);
	tmpset = p->p_siglist;
	SIGSETOR(tmpset, td->td_siglist);
	SIGSETNAND(tmpset, td->td_sigmask);
	mtx_lock(&p->p_sigacts->ps_mtx);
	SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
	mtx_unlock(&p->p_sigacts->ps_mtx);
	if (SIGNOTEMPTY(td->td_siglist) && NCP_SIGMASK(tmpset)) {
		PROC_UNLOCK(p);
                return EINTR;
	}
	PROC_UNLOCK(p);
	return 0;
}
Esempio n. 5
0
int
_sigsuspend(const sigset_t * set)
{
	struct pthread	*curthread = _get_curthread();
	int             ret = -1;
	sigset_t        oset, sigset;

	/* Check if a new signal set was provided by the caller: */
	if (set != NULL) {
		/* Save the current signal mask: */
		oset = curthread->sigmask;

		/* Change the caller's mask: */
		curthread->sigmask = *set;

		/*
		 * Check if there are pending signals for the running
		 * thread or process that aren't blocked:
		 */
		sigset = curthread->sigpend;
		SIGSETOR(sigset, _process_sigpending);
		SIGSETNAND(sigset, curthread->sigmask);
		if (SIGNOTEMPTY(sigset)) {
			/*
			 * Call the kernel scheduler which will safely
			 * install a signal frame for the running thread:
			 */
			_thread_kern_sched_sig();
		} else {
			/* Wait for a signal: */
			_thread_kern_sched_state(PS_SIGSUSPEND,
			    __FILE__, __LINE__);
		}

		/* Always return an interrupted error: */
		errno = EINTR;

		/* Restore the signal mask: */
		curthread->sigmask = oset;
	} else {
		/* Return an invalid argument error: */
		errno = EINVAL;
	}

	/* Return the completion status: */
	return (ret);
}
Esempio n. 6
0
int
_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
{
	struct pthread	*curthread = _get_curthread();
	sigset_t	sigset;
	int		ret = 0;

	/* Check if the existing signal process mask is to be returned: */
	if (oset != NULL) {
		/* Return the current mask: */
		*oset = curthread->sigmask;
	}
	/* Check if a new signal set was provided by the caller: */
	if (set != NULL) {
		/* Process according to what to do: */
		switch (how) {
		/* Block signals: */
		case SIG_BLOCK:
			/* Add signals to the existing mask: */
			SIGSETOR(curthread->sigmask, *set);
			break;

		/* Unblock signals: */
		case SIG_UNBLOCK:
			/* Clear signals from the existing mask: */
			SIGSETNAND(curthread->sigmask, *set);
			break;

		/* Set the signal process mask: */
		case SIG_SETMASK:
			/* Set the new mask: */
			curthread->sigmask = *set;
			break;

		/* Trap invalid actions: */
		default:
			/* Return an invalid argument: */
			errno = EINVAL;
			ret = -1;
			break;
		}

		/* Increment the sequence number: */
		curthread->sigmask_seqno++;

		/*
		 * Check if there are pending signals for the running
		 * thread or process that aren't blocked:
		 */
		sigset = curthread->sigpend;
		SIGSETOR(sigset, _process_sigpending);
		SIGSETNAND(sigset, curthread->sigmask);
		if (SIGNOTEMPTY(sigset))
			/*
			 * Call the kernel scheduler which will safely
			 * install a signal frame for the running thread:
			 */
			_thread_kern_sched_sig();
	}

	/* Return the completion status: */
	return (ret);
}