1// 2// Automated Testing Framework (atf) 3// 4// Copyright (c) 2007 The NetBSD Foundation, Inc. 5// All rights reserved. 6// 7// Redistribution and use in source and binary forms, with or without 8// modification, are permitted provided that the following conditions 9// are met: 10// 1. Redistributions of source code must retain the above copyright 11// notice, this list of conditions and the following disclaimer. 12// 2. Redistributions in binary form must reproduce the above copyright 13// notice, this list of conditions and the following disclaimer in the 14// documentation and/or other materials provided with the distribution. 15// 16// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29 30#if defined(HAVE_CONFIG_H) 31#include "bconfig.h" 32#endif 33 34extern "C" { 35#include <signal.h> 36#include <unistd.h> 37} 38 39#include <cerrno> 40 41#include "atf-c++/detail/exceptions.hpp" 42#include "atf-c++/detail/sanity.hpp" 43 44#include "signals.hpp" 45 46namespace impl = atf::atf_run; 47#define IMPL_NAME "atf::atf_run" 48 49const int impl::last_signo = LAST_SIGNO; 50 51// ------------------------------------------------------------------------ 52// The "signal_holder" class. 53// ------------------------------------------------------------------------ 54 55namespace { 56 57static bool happened[LAST_SIGNO + 1]; 58 59static 60void 61holder_handler(const int signo) 62{ 63 happened[signo] = true; 64} 65 66} // anonymous namespace 67 68impl::signal_holder::signal_holder(const int signo) : 69 m_signo(signo), 70 m_sp(NULL) 71{ 72 happened[signo] = false; 73 m_sp = new signal_programmer(m_signo, holder_handler); 74} 75 76impl::signal_holder::~signal_holder(void) 77{ 78 if (m_sp != NULL) 79 delete m_sp; 80 81 if (happened[m_signo]) 82 ::kill(::getpid(), m_signo); 83} 84 85void 86impl::signal_holder::process(void) 87{ 88 if (happened[m_signo]) { 89 delete m_sp; 90 m_sp = NULL; 91 happened[m_signo] = false; 92 ::kill(::getpid(), m_signo); 93 m_sp = new signal_programmer(m_signo, holder_handler); 94 } 95} 96 97// ------------------------------------------------------------------------ 98// The "signal_programmer" class. 99// ------------------------------------------------------------------------ 100 101impl::signal_programmer::signal_programmer(const int signo, const handler h) : 102 m_signo(signo), 103 m_handler(h), 104 m_programmed(false) 105{ 106 struct ::sigaction sa; 107 108 sa.sa_handler = m_handler; 109 sigemptyset(&sa.sa_mask); 110 sa.sa_flags = 0; 111 112 if (::sigaction(m_signo, &sa, &m_oldsa) == -1) 113 throw atf::system_error(IMPL_NAME, "Could not install handler for " 114 "signal", errno); 115 m_programmed = true; 116} 117 118impl::signal_programmer::~signal_programmer(void) 119{ 120 unprogram(); 121} 122 123void 124impl::signal_programmer::unprogram(void) 125{ 126 if (m_programmed) { 127 if (::sigaction(m_signo, &m_oldsa, NULL) == -1) 128 UNREACHABLE; 129 m_programmed = false; 130 } 131} 132 133// ------------------------------------------------------------------------ 134// Free functions. 135// ------------------------------------------------------------------------ 136 137void 138impl::reset(const int signo) 139{ 140 struct ::sigaction sa; 141 142 sa.sa_handler = SIG_DFL; 143 sigemptyset(&sa.sa_mask); 144 sa.sa_flags = 0; 145 146 (void)::sigaction(signo, &sa, NULL); 147} 148