/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. xrdp: A Remote Desktop Protocol server. Copyright (C) Jay Sorg 2005-2008 */ /** * * @file sig.c * @brief signal handling functions * @author Jay Sorg, Simone Fedele * */ #include "sesman.h" #include "signal.h" extern int g_sck; extern int g_pid; extern struct config_sesman* g_cfg; /******************************************************************************/ void DEFAULT_CC sig_sesman_shutdown(int sig) { log_message(&(g_cfg->log), LOG_LEVEL_INFO, "shutting down sesman %d", 1); if (g_getpid() != g_pid) { LOG_DBG(&(g_cfg->log), "g_getpid() [%d] differs from g_pid [%d]", (g_getpid()), g_pid); return; } LOG_DBG(&(g_cfg->log), " - getting signal %d pid %d", sig, g_getpid()); g_tcp_close(g_sck); session_sigkill_all(); g_file_delete(SESMAN_PID_FILE); } /******************************************************************************/ void DEFAULT_CC sig_sesman_reload_cfg(int sig) { struct config_sesman *cfg; log_message(&(g_cfg->log), LOG_LEVEL_WARNING, "receiving SIGHUP %d", 1); if (g_getpid() != g_pid) { LOG_DBG(&(g_cfg->log), "g_getpid() [%d] differs from g_pid [%d]", g_getpid(), g_pid); return; } cfg = g_malloc(sizeof(struct config_sesman), 1); if (0 == cfg) { log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "error creating new config: - keeping old cfg"); return; } if (config_read(cfg) != 0) { log_message(&(g_cfg->log), LOG_LEVEL_ERROR, "error reading config - keeping old cfg"); return; } #warning FIXME reload configuration must NOT damage logging! g_cfg = cfg; log_message(&(g_cfg->log), LOG_LEVEL_INFO, "configuration reloaded"); } /******************************************************************************/ void DEFAULT_CC sig_sesman_session_end(int sig) { int pid; if (g_getpid() != g_pid) { return; } pid = g_waitchild(); if (pid > 0) { session_kill(pid); } } /******************************************************************************/ void* DEFAULT_CC sig_handler_thread(void* arg) { int recv_signal; sigset_t sigmask; sigset_t oldmask; sigset_t waitmask; /* mask signals to be able to wait for them... */ sigfillset(&sigmask); /* it is a good idea not to block SIGILL SIGSEGV */ /* SIGFPE -- see sigaction(2) NOTES */ pthread_sigmask(SIG_BLOCK, &sigmask, &oldmask); /* building the signal wait mask... */ sigemptyset(&waitmask); sigaddset(&waitmask, SIGHUP); sigaddset(&waitmask, SIGCHLD); sigaddset(&waitmask, SIGTERM); // sigaddset(&waitmask, SIGFPE); // sigaddset(&waitmask, SIGILL); // sigaddset(&waitmask, SIGSEGV); do { LOG_DBG(&(g_cfg->log), "calling sigwait()",0); sigwait(&waitmask, &recv_signal); switch (recv_signal) { case SIGHUP: //reload cfg //we must stop & restart logging, or copy logging cfg!!!! LOG_DBG(&(g_cfg->log), "sesman received SIGHUP",0); //return 0; break; case SIGCHLD: /* a session died */ LOG_DBG(&(g_cfg->log), "sesman received SIGCHLD",0); sig_sesman_session_end(SIGCHLD); break; /*case SIGKILL; / * we die * / LOG_DBG("sesman received SIGKILL",0); sig_sesman_shutdown(recv_signal); break;*/ case SIGTERM: /* we die */ LOG_DBG(&(g_cfg->log), "sesman received SIGTERM",0); sig_sesman_shutdown(recv_signal); break; } } while (1); return 0; }