← Back to team overview

kicad-developers team mailing list archive

[PATCH] Signal handlers for SINGLE_TOP and KICAD

 

Hi,

None of the KiCad programs appear to implement any signal handlers.
This means that some of them (e.g. pcbnew) don't respond to things
like SIGINT generated by a Ctrl-C in the console its running from
(very annoying when running up and down repeatedly), and others (e.g.
eeschema) terminate immediately, rather than shutting down.

The attached patch implements a graceful shutdown on SIGINT for all of
the SINGLE_TOP programs as well as KICAD.

I have put it in a separate class (static members because the handlers
have to be that way), so that 1) the same handler can be used in both
places and 2) in future if the signal handlers grow, any complexity is
contained.

I have tested this on Linux, and since it's using the standard C++
<csignal> stuff, I assume it works (or at least compiles) on all
platforms, but I can't prove it!

Cheers,

John
From f5bb565b873d08675ae63839d229970ae9021113 Mon Sep 17 00:00:00 2001
From: John Beard <john.j.beard@xxxxxxxxx>
Date: Wed, 11 Jan 2017 22:48:57 +0800
Subject: [PATCH] Signal handlers for Kicad and Single-Top programs

This allows Kicad programs to be terminated with Ctrl-C (or SIGINT in
general) and still execute the correct shutodwn procedure. Previously,
Pcbnew wouldn't respond and eeschema would terminate immediately.

This is done in a new class with static functions, because C signal
handling only really works with static callbacks. This was done, rather
than just providing a single static function and wxApp pointer in
kicad.cpp and single_top.cpp, because this way allows for more code
reuse, and also hides future complexity if more signals are handled.
---
 common/CMakeLists.txt         |  1 +
 common/app_signal_handler.cpp | 56 ++++++++++++++++++++++++++++++++++++++
 common/single_top.cpp         |  4 +++
 include/app_signal_handler.h  | 63 +++++++++++++++++++++++++++++++++++++++++++
 kicad/kicad.cpp               |  6 ++++-
 5 files changed, 129 insertions(+), 1 deletion(-)
 create mode 100644 common/app_signal_handler.cpp
 create mode 100644 include/app_signal_handler.h

diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 210f7545a..09a5a0a0b 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -195,6 +195,7 @@ set( COMMON_SRCS
     ${COMMON_DLG_SRCS}
     ${COMMON_WIDGET_SRCS}
     ${COMMON_PAGE_LAYOUT_SRCS}
+    app_signal_handler.cpp
     base_struct.cpp
     basicframe.cpp
     bezier_curves.cpp
diff --git a/common/app_signal_handler.cpp b/common/app_signal_handler.cpp
new file mode 100644
index 000000000..b3061d6cd
--- /dev/null
+++ b/common/app_signal_handler.cpp
@@ -0,0 +1,56 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 KiCad Developers, see CHANGELOG.txt for contributors.
+ *
+ * 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, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <app_signal_handler.h>
+
+#include <csignal>
+
+
+// Initialise static members
+wxApp* AppSignalHandler::m_app = nullptr;
+
+
+void AppSignalHandler::SetSignalledApp( wxApp* app )
+{
+    m_app = app;
+}
+
+
+void AppSignalHandler::RegisterSignalHandler ( int sig,
+                              SigHandler handler)
+{
+    signal( sig, handler );
+}
+
+
+void AppSignalHandler::FatalSignalHandler( int /*sig*/ )
+{
+    if ( m_app )
+    {
+        m_app->ExitMainLoop();
+    }
+    else
+    {
+        exit( 1 );
+    }
+}
diff --git a/common/single_top.cpp b/common/single_top.cpp
index 38ed55f89..b47c60787 100644
--- a/common/single_top.cpp
+++ b/common/single_top.cpp
@@ -45,6 +45,7 @@
 #include <pgm_base.h>
 #include <kiway_player.h>
 #include <confirm.h>
+#include <app_signal_handler.h>
 
 
 // Only a single KIWAY is supported in this single_top top level component,
@@ -110,6 +111,9 @@ struct APP_SINGLE_TOP : public wxApp
 #if defined (__LINUX__)
     APP_SINGLE_TOP(): wxApp()
     {
+        // Register for signals
+        AppSignalHandler::SetSignalledApp( this );
+        AppSignalHandler::RegisterSignalHandler( SIGINT, AppSignalHandler::FatalSignalHandler );
         // Disable proxy menu in Unity window manager. Only usual menubar works with wxWidgets (at least <= 3.1)
         // When the proxy menu menubar is enable, some important things for us do not work: menuitems UI events and shortcuts.
         wxString wm;
diff --git a/include/app_signal_handler.h b/include/app_signal_handler.h
new file mode 100644
index 000000000..12f85ae88
--- /dev/null
+++ b/include/app_signal_handler.h
@@ -0,0 +1,63 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2017 KiCad Developers, see CHANGELOG.txt for contributors.
+ *
+ * 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, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#ifndef APP_SIGNAL_HANDLER_H_
+#define APP_SIGNAL_HANDLER_H_
+
+#include <wx/app.h>
+
+class AppSignalHandler
+{
+public:
+    /*!
+     * Function signature of a signal handler
+     */
+    typedef void( * SigHandler ) ( int );
+
+    /*!
+     * Set the app that the signals will be directed to
+     */
+    static void SetSignalledApp( wxApp* app );
+
+    /*!
+     * Function registerSignalHandler
+     *
+     * Register a signal handler for a set of signals
+     *
+     * @param sig the signal number to registr against
+     * @param hander the handler to register for that signal
+     */
+    static void RegisterSignalHandler ( int sig, SigHandler handler );
+
+    /*!
+     * Signal handler that gracefully shuts down the wxApp,
+     * or exits immediately if no app is set
+     */
+    static void FatalSignalHandler( int sig );
+
+private:
+
+    static wxApp* m_app;
+};
+
+#endif
diff --git a/kicad/kicad.cpp b/kicad/kicad.cpp
index 8dc657fe2..6c61d2768 100644
--- a/kicad/kicad.cpp
+++ b/kicad/kicad.cpp
@@ -38,12 +38,12 @@
 #include <kiway.h>
 #include <richio.h>
 #include <wildcards_and_files_ext.h>
+#include <app_signal_handler.h>
 
 #include "pgm_kicad.h"
 
 #include "kicad.h"
 
-
 // a dummy to quiet linking with EDA_BASE_FRAME::config();
 #include <kiface_i.h>
 KIFACE_I& Kiface()
@@ -223,6 +223,10 @@ struct APP_KICAD : public wxApp
 #if defined (__LINUX__)
     APP_KICAD(): wxApp()
     {
+        // register for signals
+        AppSignalHandler::SetSignalledApp( this );
+        AppSignalHandler::RegisterSignalHandler( SIGINT, AppSignalHandler::FatalSignalHandler );
+
         // Disable proxy menu in Unity window manager. Only usual menubar works with wxWidgets (at least <= 3.1)
         // When the proxy menu menubar is enable, some important things for us do not work: menuitems UI events and shortcuts.
         wxString wm;
-- 
2.11.0


Follow ups