Exemple #1
0
/*
  signal handler - redirects to registered signals
*/
static void tevent_common_signal_handler(int signum)
{
	struct tevent_common_signal_list *sl;
	struct tevent_context *ev = NULL;
	int saved_errno = errno;

	TEVENT_SIG_INCREMENT(sig_state->signal_count[signum]);
	TEVENT_SIG_INCREMENT(sig_state->got_signal);

	/* Write to each unique event context. */
	for (sl = sig_state->sig_handlers[signum]; sl; sl = sl->next) {
		if (sl->se->event_ctx && sl->se->event_ctx != ev) {
			ev = sl->se->event_ctx;
			tevent_common_wakeup(ev);
		}
	}

	errno = saved_errno;
}
Exemple #2
0
/*
  signal handler - redirects to registered signals
*/
static void tevent_common_signal_handler(int signum)
{
	char c = 0;
	struct tevent_common_signal_list *sl;
	struct tevent_context *ev = NULL;
	int saved_errno = errno;

	TEVENT_SIG_INCREMENT(sig_state->signal_count[signum]);
	TEVENT_SIG_INCREMENT(sig_state->got_signal);

	/* Write to each unique event context. */
	for (sl = sig_state->sig_handlers[signum]; sl; sl = sl->next) {
		if (sl->se->event_ctx && sl->se->event_ctx != ev) {
			ev = sl->se->event_ctx;
			/* doesn't matter if this pipe overflows */
			(void) write(ev->pipe_fds[1], &c, 1);
		}
	}

	errno = saved_errno;
}
Exemple #3
0
/*
  signal handler with SA_SIGINFO - redirects to registered signals
*/
static void tevent_common_signal_handler_info(int signum, siginfo_t *info,
					      void *uctx)
{
	uint32_t count = tevent_sig_count(sig_state->signal_count[signum]);
	/* sig_state->signal_count[signum].seen % TEVENT_SA_INFO_QUEUE_COUNT
	 * is the base of the unprocessed signals in the ringbuffer. */
	uint32_t ofs = (sig_state->signal_count[signum].seen + count) %
				TEVENT_SA_INFO_QUEUE_COUNT;
	sig_state->sig_info[signum][ofs] = *info;

	tevent_common_signal_handler(signum);

	/* handle SA_SIGINFO */
	if (count+1 == TEVENT_SA_INFO_QUEUE_COUNT) {
		/* we've filled the info array - block this signal until
		   these ones are delivered */
#ifdef HAVE_UCONTEXT_T
		/*
		 * This is the only way for this to work.
		 * By default signum is blocked inside this
		 * signal handler using a temporary mask,
		 * but what we really need to do now is
		 * block it in the callers mask, so it
		 * stays blocked when the temporary signal
		 * handler mask is replaced when we return
		 * from here. The callers mask can be found
		 * in the ucontext_t passed in as the
		 * void *uctx argument.
		 */
		ucontext_t *ucp = (ucontext_t *)uctx;
		sigaddset(&ucp->uc_sigmask, signum);
#else
		/*
		 * WARNING !!! WARNING !!!!
		 *
		 * This code doesn't work.
		 * By default signum is blocked inside this
		 * signal handler, but calling sigprocmask
		 * modifies the temporary signal mask being
		 * used *inside* this handler, which will be
		 * replaced by the callers signal mask once
		 * we return from here. See Samba
		 * bug #9550 for details.
		 */
		sigset_t set;
		sigemptyset(&set);
		sigaddset(&set, signum);
		sigprocmask(SIG_BLOCK, &set, NULL);
#endif
		TEVENT_SIG_INCREMENT(sig_state->sig_blocked[signum]);
	}
}
Exemple #4
0
/*
  signal handler with SA_SIGINFO - redirects to registered signals
*/
static void tevent_common_signal_handler_info(int signum, siginfo_t *info,
					      void *uctx)
{
	uint32_t count = tevent_sig_count(sig_state->signal_count[signum]);
	/* sig_state->signal_count[signum].seen % TEVENT_SA_INFO_QUEUE_COUNT
	 * is the base of the unprocessed signals in the ringbuffer. */
	uint32_t ofs = (sig_state->signal_count[signum].seen + count) %
				TEVENT_SA_INFO_QUEUE_COUNT;
	sig_state->sig_info[signum][ofs] = *info;

	tevent_common_signal_handler(signum);

	/* handle SA_SIGINFO */
	if (count+1 == TEVENT_SA_INFO_QUEUE_COUNT) {
		/* we've filled the info array - block this signal until
		   these ones are delivered */
		sigset_t set;
		sigemptyset(&set);
		sigaddset(&set, signum);
		sigprocmask(SIG_BLOCK, &set, NULL);
		TEVENT_SIG_INCREMENT(sig_state->sig_blocked[signum]);
	}
}