octruntime.swg: do not use atexit() to quit Octave

- This reverts commit 931656bcbe7c2bf37bb5d831b47fab9a38695e91
- Since atexit() does not pass along the desired exit status,
  __swig_atexit__() always exits with status zero, regardless
  of whether Octave completed successfully or raised an error.
- This means the success/failure of Octave scripts which load
  SWIG modules cannot be determined by other programs, which
  makes them unusable.
- Instead, provide a Octave function swig_exit() which calls
  ::_Exit() with a given exit status. This way at least a
  clean exit from Octave can be guaranteed for future versions
  if the seg-fault problem is not fixed.
diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg
index 6e07aaa..2f0cf58 100644
--- a/Lib/octave/octruntime.swg
+++ b/Lib/octave/octruntime.swg
@@ -315,13 +315,29 @@
   return octave_value(prereq);
 }
 
+static const char *const swig_exit_usage = "-*- texinfo -*- \n\
+@deftypefn {Loadable Function} {} swig_exit([@var{exit_status}])\n\
+Exit Octave without performing any memory cleanup.\n\
+@end deftypefn";
+
+DEFUN_DLD( swig_exit, args, nargout, swig_exit_usage ) {
+  if (args.length() > 1) {
+    error("swig_exit: must be called with at most one arguments");
+    return octave_value_list();
+  }
+  int exit_status = 0;
+  if (args.length() == 1) {
+    exit_status = args(0).int_value();
+  }
+  ::_Exit(exit_status);
+  return octave_value();
+}
+
 static const char *const SWIG_name_usage = "-*- texinfo -*- \n\
 @deftypefn {Loadable Module} {} " SWIG_name_d "\n\
 Loads the SWIG-generated module `" SWIG_name_d "'.\n\
 @end deftypefn";
 
-void __swig_atexit__(void) { ::_Exit(0); }
-
 DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
 
   static octave_swig_type* module_ns = 0;
@@ -329,15 +345,16 @@
   // workaround to prevent octave seg-faulting on exit: set Octave exit function
   // octave_exit to _Exit, which exits immediately without trying to cleanup memory.
   // definitely affected version 3.2.*, not sure about 3.3.*, seems to be fixed in
-  // version 3.4.*, but reappeared in 4.2.*, so turn on for all versions after 3.2.*.
+  // version 3.4.*, reappeared in 4.2.*, hack not possible in 4.4.* or later due to
+  // removal of octave_exit, so turn on for all versions between 3.2.*. and 4.4.*.
   // can be turned off with macro definition.
 #ifndef SWIG_OCTAVE_NO_SEGFAULT_HACK
-#if SWIG_OCTAVE_PREREQ(4,4,0)
-  atexit(__swig_atexit__);
-#elif SWIG_OCTAVE_PREREQ(3,2,0)
+#if !SWIG_OCTAVE_PREREQ(4,4,0)
+#if SWIG_OCTAVE_PREREQ(3,2,0)
   octave_exit = ::_Exit;
 #endif
 #endif
+#endif
 
   // check for no input and output args
   if (args.length() != 0 || nargout != 0) {
@@ -420,6 +437,9 @@
     if (!SWIG_Octave_InstallFunction(me, "swig_octave_prereq")) {
       return octave_value_list();
     }
+    if (!SWIG_Octave_InstallFunction(me, "swig_exit")) {
+      return octave_value_list();
+    }
 
     octave_swig_type* cvar_ns=0;
     if (std::string(SWIG_global_name) != ".") {