Exemple #1
0
int
sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
	struct sigaction sa;

	if (sig == SIGTHR) {
		errno = EINVAL;
		return (-1);
	}
	if (act != NULL && sigismember(&act->sa_mask, SIGTHR)) {
		sa = *act;
		sigdelset(&sa.sa_mask, SIGTHR);
		act = &sa;
	}
	return (_thread_sys_sigaction(sig, act, oact));
}
Exemple #2
0
void
_thread_exit(const char *fname, int lineno, const char *string)
{
	char            s[256];

	/* Prepare an error message string: */
	s[0] = '\0';
	strlcat(s, "pid ", sizeof s);
	numlcat(s, (int)_thread_sys_getpid(), sizeof s);
	strlcat(s, ": Fatal error '", sizeof s);
	strlcat(s, string, sizeof s);
	strlcat(s, "' at line ", sizeof s);
	numlcat(s, lineno, sizeof s);
	strlcat(s, " in file ", sizeof s);
	strlcat(s, fname, sizeof s);
	strlcat(s, " (errno = ", sizeof s);
	numlcat(s, errno, sizeof s);
	strlcat(s, ")\n", sizeof s);

	/* Write the string to the standard error file descriptor: */
	_thread_sys_write(2, s, strlen(s));

	/* Force this process to exit: */
	/* XXX - Do we want abort to be conditional on _PTHREADS_INVARIANTS? */
#if defined(_PTHREADS_INVARIANTS)
	{
		struct sigaction sa;
		sigset_t s;

		/* Ignore everything except ABORT */
		sigfillset(&s);
		sigdelset(&s, SIGABRT);
		_thread_sys_sigprocmask(SIG_SETMASK, &s, NULL);

		/* Set the abort handler to default (dump core) */
		sa.sa_handler = SIG_DFL;
		sigemptyset(&sa.sa_mask);
		sa.sa_flags = SA_SIGINFO;
		(void)_thread_sys_sigaction(SIGABRT, &sa, NULL);
		(void)_thread_sys_kill(_thread_sys_getpid(), SIGABRT);
		for (;;) ;
	}
#else
	_exit(1);
#endif
}
sig_t
_thread_sys_signal(int s, sig_t a)
{
	struct sigaction sa;
	struct sigaction osa;

	/* Initialise the signal action structure: */
	sigemptyset(&sa.sa_mask);
	sa.sa_handler = a;
	sa.sa_flags = SA_SIGINFO;

	/* Perform the sigaction syscall: */
	if (_thread_sys_sigaction(s, &sa, &osa) < 0) {
		/* Return an error: */
		return (SIG_ERR);
	}
	/* Return a pointer to the old signal handler: */
	return (osa.sa_handler);
}
int
sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
{
	int ret = 0;
	struct sigaction gact;

	/* Check if the signal number is out of range: */
	if (sig < 1 || sig >= NSIG) {
		/* Return an invalid argument: */
		errno = EINVAL;
		ret = -1;
	} else {
		/*
		 * Check if the existing signal action structure contents are
		 * to be returned: 
		 */
		if (oact != NULL) {
			/* Return the existing signal action contents: */
			oact->sa_handler = _thread_sigact[sig - 1].sa_handler;
			oact->sa_mask = _thread_sigact[sig - 1].sa_mask;
			oact->sa_flags = _thread_sigact[sig - 1].sa_flags;
		}

		/* Check if a signal action was supplied: */
		if (act != NULL) {
			/* Set the new signal handler: */
			_thread_sigact[sig - 1].sa_mask = act->sa_mask;
			_thread_sigact[sig - 1].sa_flags = act->sa_flags;
			_thread_sigact[sig - 1].sa_handler = act->sa_handler;
		}

		/*
		 * Check if the kernel needs to be advised of a change
		 * in signal action:
		 */
		if (act != NULL && sig != _SCHED_SIGNAL && sig != SIGCHLD &&
		    sig != SIGINFO) {
			gact.sa_mask = act->sa_mask;
			sigaddset(&gact.sa_mask, _SCHED_SIGNAL);
			gact.sa_flags = act->sa_flags | SA_SIGINFO;

			/*
			 * Check if the signal handler is being set to
			 * the default or ignore handlers:
			 */
			if (act->sa_handler == SIG_DFL ||
			    act->sa_handler == SIG_IGN)
				/* Specify the built in handler: */
				gact.sa_handler = act->sa_handler;
			else
				/* Specify the thread kernel signal handler */
				gact.sa_handler =
					(void (*) (int)) _thread_sig_handler;

			/* Change the signal action in the kernel: */
		    	if (_thread_sys_sigaction(sig, &gact, NULL) != 0)
				ret = -1;
		}
	}

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