Home | History | Annotate | Line # | Download | only in gdbsupport
      1  1.1  christos /* RAII class to install a separate handler for a given signal
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2024 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #ifndef SCOPED_SIGNAL_HANDLER_H
     21  1.1  christos #define SCOPED_SIGNAL_HANDLER_H
     22  1.1  christos 
     23  1.1  christos #include <signal.h>
     24  1.1  christos 
     25  1.1  christos #undef HAVE_SIGACTION
     26  1.1  christos 
     27  1.1  christos /* RAII class to set a signal handler for a scope, that will take care of
     28  1.1  christos    unsetting the handler when the scope is left.
     29  1.1  christos    This class will try to use sigaction whenever available, following the
     30  1.1  christos    recommendation on the man page for signal, and only fallback to signal
     31  1.1  christos    if necessary.  */
     32  1.1  christos template <int SIG>
     33  1.1  christos class scoped_signal_handler
     34  1.1  christos {
     35  1.1  christos public:
     36  1.1  christos   scoped_signal_handler (sighandler_t handler)
     37  1.1  christos   {
     38  1.1  christos #if defined (HAVE_SIGACTION)
     39  1.1  christos     struct sigaction act;
     40  1.1  christos 
     41  1.1  christos     act.sa_handler = handler;
     42  1.1  christos     sigemptyset (&act.sa_mask);
     43  1.1  christos     act.sa_flags = 0;
     44  1.1  christos     sigaction (SIG, &act, &m_prev_handler);
     45  1.1  christos #else
     46  1.1  christos     /* The return of the function call is the previous signal handler, or
     47  1.1  christos        SIG_ERR if the function doesn't succeed.  */
     48  1.1  christos     m_prev_handler = signal (SIG, handler);
     49  1.1  christos     /* According to the GNU libc manual, the only way signal fails is if
     50  1.1  christos        the signum given is invalid, so we should be safe to assert.  */
     51  1.1  christos     gdb_assert (m_prev_handler != SIG_ERR);
     52  1.1  christos #endif
     53  1.1  christos   }
     54  1.1  christos 
     55  1.1  christos   ~scoped_signal_handler ()
     56  1.1  christos   {
     57  1.1  christos #if defined (HAVE_SIGACTION)
     58  1.1  christos     sigaction (SIG, &m_prev_handler, nullptr);
     59  1.1  christos #else
     60  1.1  christos     signal (SIG, m_prev_handler);
     61  1.1  christos #endif
     62  1.1  christos   }
     63  1.1  christos 
     64  1.1  christos   DISABLE_COPY_AND_ASSIGN (scoped_signal_handler);
     65  1.1  christos private:
     66  1.1  christos #if defined (HAVE_SIGACTION)
     67  1.1  christos   struct sigaction m_prev_handler;
     68  1.1  christos #else
     69  1.1  christos   sighandler_t m_prev_handler;
     70  1.1  christos #endif
     71  1.1  christos };
     72  1.1  christos 
     73  1.1  christos #endif /* SCOPED_SIGNAL_HANDLER_H  */
     74