/*

Copyright (C) 2015, 2016 Olaf Till <i7tiol@t-online.de>

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, see <http://www.gnu.org/licenses/>.

*/

#ifndef __OCT_PARALLEL_SIGHANDLER__

#define __OCT_PARALLEL_SIGHANDLER__

#include <signal.h>

#include <stdio.h>

class
inthandler_dont_restart_syscalls
{
public:
  inthandler_dont_restart_syscalls (void)
  : restore_int (false), restore_break (false)
  {
#ifdef SIGINT
    if (sigaction (SIGINT, NULL, &oldintaction))
      return;

    restore_int = true;

    memcpy (&newintaction, &oldintaction, sizeof (struct sigaction));

    newintaction.sa_flags &= ~ SA_RESTART;

    sigaction (SIGINT, &newintaction, NULL);
#endif

#ifdef SIGBREAK
    if (sigaction (SIGBREAK, NULL, &oldbreakaction))
      return;

    restore_break = true;

    memcpy (&newbreakaction, &oldbreakaction, sizeof (struct sigaction));

    newbreakaction.sa_flags &= ~ SA_RESTART;

    sigaction (SIGBREAK, &newbreakaction, NULL);
#endif
  }

  ~inthandler_dont_restart_syscalls (void)
  {
#ifdef SIGINT
    if (restore_int)
      sigaction (SIGINT, &oldintaction, NULL);
#endif

#ifdef SIGBREAK
    if (restore_break)
      sigaction (SIGBREAK, &oldbreakaction, NULL);
#endif
  }

private:

  bool restore_int;

  bool restore_break;

#ifdef SIGINT
  struct sigaction newintaction;

  struct sigaction oldintaction;
#endif

#ifdef SIGBREAK
  struct sigaction newbreakaction;

  struct sigaction oldbreakaction;
#endif
};

#endif // __OCT_PARALLEL_SIGHANDLER__
