Blame libfreerdp/utils/signal.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * FreeRDP: A Remote Desktop Protocol Implementation
Packit 1fb8d4
 * Signal handling
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2011 Shea Levy <shea@shealevy.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <stddef.h>
Packit 1fb8d4
#include <errno.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
Packit 1fb8d4
#include <freerdp/utils/signal.h>
Packit 1fb8d4
#include <freerdp/log.h>
Packit 1fb8d4
Packit 1fb8d4
#define TAG FREERDP_TAG("utils")
Packit 1fb8d4
Packit 1fb8d4
#ifdef _WIN32
Packit 1fb8d4
Packit 1fb8d4
int freerdp_handle_signals(void)
Packit 1fb8d4
{
Packit 1fb8d4
	errno = ENOSYS;
Packit 1fb8d4
	return -1;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#else
Packit 1fb8d4
Packit 1fb8d4
#include <pthread.h>
Packit 1fb8d4
Packit 1fb8d4
volatile sig_atomic_t terminal_needs_reset = 0;
Packit 1fb8d4
int terminal_fildes = 0;
Packit 1fb8d4
struct termios orig_flags;
Packit 1fb8d4
struct termios new_flags;
Packit 1fb8d4
Packit 1fb8d4
static void fatal_handler(int signum)
Packit 1fb8d4
{
Packit 1fb8d4
	struct sigaction default_sigaction;
Packit 1fb8d4
	sigset_t this_mask;
Packit 1fb8d4
	WLog_DBG(TAG, "fatal_handler: signum=%d", signum);
Packit 1fb8d4
Packit 1fb8d4
	if (terminal_needs_reset)
Packit 1fb8d4
		tcsetattr(terminal_fildes, TCSAFLUSH, &orig_flags);
Packit 1fb8d4
Packit 1fb8d4
	default_sigaction.sa_handler = SIG_DFL;
Packit 1fb8d4
	sigfillset(&(default_sigaction.sa_mask));
Packit 1fb8d4
	default_sigaction.sa_flags = 0;
Packit 1fb8d4
	sigaction(signum, &default_sigaction, NULL);
Packit 1fb8d4
	sigemptyset(&this_mask);
Packit 1fb8d4
	sigaddset(&this_mask, signum);
Packit 1fb8d4
	pthread_sigmask(SIG_UNBLOCK, &this_mask, NULL);
Packit 1fb8d4
	raise(signum);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
const int fatal_signals[] =
Packit 1fb8d4
{
Packit 1fb8d4
	SIGABRT,
Packit 1fb8d4
	SIGALRM,
Packit 1fb8d4
	SIGBUS,
Packit 1fb8d4
	SIGFPE,
Packit 1fb8d4
	SIGHUP,
Packit 1fb8d4
	SIGILL,
Packit 1fb8d4
	SIGINT,
Packit 1fb8d4
	SIGKILL,
Packit 1fb8d4
	SIGQUIT,
Packit 1fb8d4
	SIGSEGV,
Packit 1fb8d4
	SIGSTOP,
Packit 1fb8d4
	SIGTERM,
Packit 1fb8d4
	SIGTSTP,
Packit 1fb8d4
	SIGTTIN,
Packit 1fb8d4
	SIGTTOU,
Packit 1fb8d4
	SIGUSR1,
Packit 1fb8d4
	SIGUSR2,
Packit 1fb8d4
#ifdef SIGPOLL
Packit 1fb8d4
	SIGPOLL,
Packit 1fb8d4
#endif
Packit 1fb8d4
#ifdef SIGPROF
Packit 1fb8d4
	SIGPROF,
Packit 1fb8d4
#endif
Packit 1fb8d4
#ifdef SIGSYS
Packit 1fb8d4
	SIGSYS,
Packit 1fb8d4
#endif
Packit 1fb8d4
	SIGTRAP,
Packit 1fb8d4
#ifdef SIGVTALRM
Packit 1fb8d4
	SIGVTALRM,
Packit 1fb8d4
#endif
Packit 1fb8d4
	SIGXCPU,
Packit 1fb8d4
	SIGXFSZ
Packit 1fb8d4
};
Packit 1fb8d4
Packit 1fb8d4
int freerdp_handle_signals(void)
Packit 1fb8d4
{
Packit 1fb8d4
	size_t signal_index;
Packit 1fb8d4
	sigset_t orig_set;
Packit 1fb8d4
	struct sigaction orig_sigaction;
Packit 1fb8d4
	struct sigaction fatal_sigaction;
Packit 1fb8d4
	WLog_DBG(TAG, "Registering signal hook...");
Packit 1fb8d4
	sigfillset(&(fatal_sigaction.sa_mask));
Packit 1fb8d4
	sigdelset(&(fatal_sigaction.sa_mask), SIGCONT);
Packit 1fb8d4
	pthread_sigmask(SIG_BLOCK, &(fatal_sigaction.sa_mask), &orig_set);
Packit 1fb8d4
	fatal_sigaction.sa_handler = fatal_handler;
Packit 1fb8d4
	fatal_sigaction.sa_flags  = 0;
Packit 1fb8d4
Packit 1fb8d4
	for (signal_index = 0; signal_index < ARRAYSIZE(fatal_signals); signal_index++)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (sigaction(fatal_signals[signal_index], NULL, &orig_sigaction) == 0)
Packit 1fb8d4
		{
Packit 1fb8d4
			if (orig_sigaction.sa_handler != SIG_IGN)
Packit 1fb8d4
			{
Packit 1fb8d4
				sigaction(fatal_signals[signal_index], &fatal_sigaction, NULL);
Packit 1fb8d4
			}
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	pthread_sigmask(SIG_SETMASK, &orig_set, NULL);
Packit 1fb8d4
	/* Ignore SIGPIPE signal. */
Packit 1fb8d4
	signal(SIGPIPE, SIG_IGN);
Packit 1fb8d4
	return 0;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif