Exemplo n.º 1
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);
}
Exemplo n.º 2
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);
}