changeset 17778:b5d58667d32d

new main program wrapper to handle giving up controlling tty * octave-gui.cc (octave_cli_thread): New class, from QtHandles. (dissociate_terminal): Delete. (octave_start_gui): Third arg is now START_GUI instead of FORK. Don't call dissociate_terminal. If start_gui is false, use octave_cli_thread to start Octave within a QApplication context. * sighandlers.cc (gui_driver_sig_handler): Move to src/main.in.cc. (install_gui_driver_signal_handlers): Move to src/main.in.cc and rename to octave_set_signal_handler. * octave.cc (no_fork_option): Delete. (process_command_line): Don't handle NO_FORK_OPTION. (octave_fork_gui): Move to src/main.in.cc and rename to have_controlling_terminal. * options-usage.h (usage_string, octave_print_verbose_usage_and_exit): Delete --no-fork from text. (long_opts): Delete no-fork from list. (NO_FORK_OPTION): Delete. * run-octave.in: Set OCTAVE_BINDIR in environment before exec-ing Octave binary. * src/Makefile.am: Build octave-gui, octave-cli, and octave instead of octave-cli and octave. * main-gui.cc: Rename from main.cc. Call octave_start_gui and pass START_GUI as parameter. * main.in.cc: New file.
author John W. Eaton <jwe@octave.org>
date Sun, 27 Oct 2013 18:47:22 -0400
parents ae8905fbf1f8
children 9244d2a908fd
files libgui/src/octave-gui.cc libgui/src/octave-gui.h libinterp/corefcn/sighandlers.cc libinterp/corefcn/sighandlers.h libinterp/octave.cc libinterp/options-usage.h run-octave.in src/Makefile.am src/main-gui.cc src/main.cc src/main.in.cc
diffstat 11 files changed, 621 insertions(+), 348 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/octave-gui.cc	Sun Oct 27 08:40:54 2013 -0400
+++ b/libgui/src/octave-gui.cc	Sun Oct 27 18:47:22 2013 -0400
@@ -24,8 +24,9 @@
 #include <config.h>
 #endif
 
-#include <QtGui/QApplication>
+#include <QApplication>
 #include <QTextCodec>
+#include <QThread>
 #include <QTranslator>
 
 #include <iostream>
@@ -42,6 +43,7 @@
 #include "oct-syscalls.h"
 #include "syswait.h"
 
+#include "octave.h"
 #include "sighandlers.h"
 
 #include "welcome-wizard.h"
@@ -49,6 +51,37 @@
 #include "main-window.h"
 #include "octave-gui.h"
 
+// Allow the Octave interpreter to start as in CLI mode with a
+// QApplication context so that it can use Qt for things like plotting
+// and UI widgets.
+
+class octave_cli_thread : public QThread
+{
+public:
+
+  octave_cli_thread (int argc, char **argv)
+    : m_argc (argc), m_argv (argv), m_result (0) { }
+
+  int result (void) const { return m_result; }
+
+protected:
+
+  void run (void)
+  {
+    octave_initialize_interpreter (m_argc, m_argv, 0);
+
+    m_result = octave_execute_interpreter ();
+
+    QApplication::exit (m_result);
+  }
+
+private:
+
+  int m_argc;
+  char** m_argv;
+  int m_result;
+};
+
 
 // Custom message handler for filtering some messages from Qt.
 
@@ -78,104 +111,75 @@
      }
  }
 
-
-// Dissociate from the controlling terminal, if any.
+// If START_GUI is false, we still set up the QApplication so that we
+// can use Qt widgets for plot windows.
 
-static void
-dissociate_terminal (void)
+int
+octave_start_gui (int argc, char *argv[], bool start_gui)
 {
-#if ! (defined (__WIN32__) || defined (__APPLE__)) || defined (__CYGWIN__)
- 
-  pid_t pid = fork ();
+  qInstallMsgHandler (message_handler);
 
-  if (pid < 0)
+  QApplication application (argc, argv);
+
+  if (start_gui)
     {
-      std::cerr << "fork failed!" << std::endl;;
-      exit (1);
-    }
-  else if (pid == 0)
-    {
-      // Child.
+      // Set the codec for all strings
+      QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
+
+      // install translators for the gui and qt text
+      QTranslator gui_tr, qt_tr, qsci_tr;
+      resource_manager::config_translators (&qt_tr,&qsci_tr,&gui_tr);
+      application.installTranslator (&qt_tr);
+      application.installTranslator (&qsci_tr);
+      application.installTranslator (&gui_tr);
+
+      while (true)
+        {
+          if (resource_manager::is_first_run ())
+            {
+              welcome_wizard welcomeWizard;
+              welcomeWizard.exec ();
+              resource_manager::reload_settings ();
+            }
+          else
+            {
+              // update network-settings
+              resource_manager::update_network_settings ();
 
-      if (setsid () < 0)
-        {
-          std::cerr << "setsid error" << std::endl;
-          exit (1);
+#if ! defined (__WIN32__) || defined (__CYGWIN__)
+              // If we were started from a launcher, TERM might not be
+              // defined, but we provide a terminal with xterm
+              // capabilities.
+
+              std::string term = octave_env::getenv ("TERM");
+
+              if (term.empty ())
+                octave_env::putenv ("TERM", "xterm");
+#else
+              std::string term = octave_env::getenv ("TERM");
+
+              if (term.empty ())
+                octave_env::putenv ("TERM", "cygwin");
+#endif
+
+              // create main window, read settings, and show window
+              main_window w;
+              w.read_settings ();  // get widget settings and window layout
+              w.focus_command_window ();
+              w.connect_visibility_changed (); // connect signals for changes in
+              // visibility not before w is shown
+              return application.exec ();
+            }
         }
     }
   else
     {
-      // Parent
-
-      install_gui_driver_signal_handlers (pid);
-
-      int status;
-
-      waitpid (pid, &status, 0);
-
-      exit (octave_wait::ifexited (status)
-            ? octave_wait::exitstatus (status) : 127);
-    }
-
-#endif
-}
+      octave_cli_thread main_thread (argc, argv);
 
-int
-octave_start_gui (int argc, char *argv[], bool fork)
-{
-  if (fork)
-    dissociate_terminal ();
-
-  qInstallMsgHandler (message_handler);
-
-  QApplication application (argc, argv);
-
-  // Set the codec for all strings
-  QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
-
-  // install translators for the gui and qt text
-  QTranslator gui_tr, qt_tr, qsci_tr;
-  resource_manager::config_translators (&qt_tr,&qsci_tr,&gui_tr);
-  application.installTranslator (&qt_tr);
-  application.installTranslator (&qsci_tr);
-  application.installTranslator (&gui_tr);
+      application.setQuitOnLastWindowClosed (false);
 
-  while (true)
-    {
-      if (resource_manager::is_first_run ())
-        {
-          welcome_wizard welcomeWizard;
-          welcomeWizard.exec ();
-          resource_manager::reload_settings ();
-        }
-      else
-        {
-          // update network-settings
-          resource_manager::update_network_settings ();
-
-#if ! defined (__WIN32__) || defined (__CYGWIN__)
-          // If we were started from a launcher, TERM might not be
-          // defined, but we provide a terminal with xterm
-          // capabilities.
+      main_thread.start ();
 
-          std::string term = octave_env::getenv ("TERM");
-
-          if (term.empty ())
-            octave_env::putenv ("TERM", "xterm");
-#else
-          std::string term = octave_env::getenv ("TERM");
-
-          if (term.empty ())
-            octave_env::putenv ("TERM", "cygwin");
-#endif
-
-          // create main window, read settings, and show window
-          main_window w;
-          w.read_settings ();  // get widget settings and window layout
-          w.focus_command_window ();
-          w.connect_visibility_changed (); // connect signals for changes in
-                                           // visibility not before w is shown
-          return application.exec ();
-        }
+      return application.exec ();
     }
 }
--- a/libgui/src/octave-gui.h	Sun Oct 27 08:40:54 2013 -0400
+++ b/libgui/src/octave-gui.h	Sun Oct 27 18:47:22 2013 -0400
@@ -24,6 +24,6 @@
 #define octave_octave_gui_h 1
 
 extern OCTGUI_API int octave_start_gui (int argc, char **argv,
-                                        bool fork = true);
+                                        bool start_gui = true);
 
 #endif
--- a/libinterp/corefcn/sighandlers.cc	Sun Oct 27 08:40:54 2013 -0400
+++ b/libinterp/corefcn/sighandlers.cc	Sun Oct 27 18:47:22 2013 -0400
@@ -577,137 +577,6 @@
 
 }
 
-static pid_t gui_pid = 0;
-
-static void
-gui_driver_sig_handler (int sig)
-{
-  if (gui_pid > 0)
-    octave_syscalls::kill (gui_pid, sig);
-}
-
-void
-install_gui_driver_signal_handlers (pid_t pid)
-{
-  gui_pid = pid;
-
-#ifdef SIGINT
-  octave_set_signal_handler (SIGINT, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGBREAK
-  octave_set_signal_handler (SIGBREAK, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGABRT
-  octave_set_signal_handler (SIGABRT, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGALRM
-  octave_set_signal_handler (SIGALRM, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGBUS
-  octave_set_signal_handler (SIGBUS, gui_driver_sig_handler);
-#endif
-
-  // SIGCHLD
-  // SIGCLD
-  // SIGCONT
-
-#ifdef SIGEMT
-  octave_set_signal_handler (SIGEMT, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGFPE
-  octave_set_signal_handler (SIGFPE, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGHUP
-  octave_set_signal_handler (SIGHUP, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGILL
-  octave_set_signal_handler (SIGILL, gui_driver_sig_handler);
-#endif
-
-  // SIGINFO
-  // SIGINT
-
-#ifdef SIGIOT
-  octave_set_signal_handler (SIGIOT, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGLOST
-  octave_set_signal_handler (SIGLOST, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGPIPE
-  octave_set_signal_handler (SIGPIPE, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGPOLL
-  octave_set_signal_handler (SIGPOLL, gui_driver_sig_handler);
-#endif
-
-  // SIGPROF
-  // SIGPWR
-
-#ifdef SIGQUIT
-  octave_set_signal_handler (SIGQUIT, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGSEGV
-  octave_set_signal_handler (SIGSEGV, gui_driver_sig_handler);
-#endif
-
-  // SIGSTOP
-
-#ifdef SIGSYS
-  octave_set_signal_handler (SIGSYS, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGTERM
-  octave_set_signal_handler (SIGTERM, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGTRAP
-  octave_set_signal_handler (SIGTRAP, gui_driver_sig_handler);
-#endif
-
-  // SIGTSTP
-  // SIGTTIN
-  // SIGTTOU
-  // SIGURG
-
-#ifdef SIGUSR1
-  octave_set_signal_handler (SIGUSR1, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGUSR2
-  octave_set_signal_handler (SIGUSR2, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGVTALRM
-  octave_set_signal_handler (SIGVTALRM, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGIO
-  octave_set_signal_handler (SIGIO, gui_driver_sig_handler);
-#endif
-
-  // SIGWINCH
-
-#ifdef SIGXCPU
-  octave_set_signal_handler (SIGXCPU, gui_driver_sig_handler);
-#endif
-
-#ifdef SIGXFSZ
-  octave_set_signal_handler (SIGXFSZ, gui_driver_sig_handler);
-#endif
-
-}
-
 static octave_scalar_map
 make_sig_struct (void)
 {
--- a/libinterp/corefcn/sighandlers.h	Sun Oct 27 08:40:54 2013 -0400
+++ b/libinterp/corefcn/sighandlers.h	Sun Oct 27 18:47:22 2013 -0400
@@ -71,8 +71,6 @@
 
 extern OCTINTERP_API void install_signal_handlers (void);
 
-extern OCTINTERP_API void install_gui_driver_signal_handlers (pid_t pid);
-
 extern OCTINTERP_API void octave_signal_handler (void);
 
 extern OCTINTERP_API octave_interrupt_handler octave_catch_interrupts (void);
--- a/libinterp/octave.cc	Sun Oct 27 08:40:54 2013 -0400
+++ b/libinterp/octave.cc	Sun Oct 27 18:47:22 2013 -0400
@@ -128,10 +128,6 @@
 // (--force-gui)
 static bool force_gui_option = false;
 
-// If TRUE don't fork when starting the GUI.
-// (--no-fork)
-static bool no_fork_option = false;
-
 // If TRUE don't start the GUI.
 // (--no-gui)
 static bool no_gui_option = false;
@@ -647,10 +643,6 @@
           forced_line_editing = true;
           break;
 
-        case NO_FORK_OPTION:
-          no_fork_option = true;
-          break;
-
         case NO_GUI_OPTION:
           no_gui_option = true;
           break;
@@ -938,26 +930,6 @@
   return start_gui;
 }
 
-int
-octave_fork_gui (void)
-{
-  bool have_ctty = false;
-
-#if ! (defined (__WIN32__) || defined (__APPLE__)) || defined (__CYGWIN__)
-
-#if defined (HAVE_CTERMID)
-  const char *ctty = ctermid (0);
-#else
-  const char *ctty = "/dev/tty";
-#endif
-
-  have_ctty = gnulib::open (ctty, O_RDWR, 0) > 0;
-
-#endif
-
-  return (have_ctty && ! no_fork_option);
-}
-
 DEFUN (isguirunning, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} isguirunning ()\n\
--- a/libinterp/options-usage.h	Sun Oct 27 08:40:54 2013 -0400
+++ b/libinterp/options-usage.h	Sun Oct 27 18:47:22 2013 -0400
@@ -33,11 +33,11 @@
        [--echo-commands] [--eval CODE] [--exec-path path]\n\
        [--force-gui] [--help] [--image-path path]\n\
        [--info-file file] [--info-program prog] [--interactive]\n\
-       [--line-editing] [--no-fork] [--no-gui] [--no-history]\n\
-       [--no-init-file] [--no-init-path] [--no-jit-compiler]\n\
-       [--no-line-editing] [--no-site-file] [--no-window-system]\n\
-       [--norc] [-p path] [--path path] [--persist] [--silent]\n\
-       [--traditional] [--verbose] [--version] [file]";
+       [--line-editing] [--no-gui] [--no-history] [--no-init-file]\n\
+       [--no-init-path] [--no-jit-compiler] [--no-line-editing]\n\
+       [--no-site-file] [--no-window-system] [--norc] [-p path]\n\
+       [--path path] [--persist] [--silent] [--traditional]\n\
+       [--verbose] [--version] [file]";
 
 // This is here so that it's more likely that the usage message and
 // the real set of options will agree.  Note: the '+' must come first
@@ -56,16 +56,15 @@
 #define INFO_PROG_OPTION 8
 #define DEBUG_JIT_OPTION 9
 #define LINE_EDITING_OPTION 10
-#define NO_FORK_OPTION 11
-#define NO_GUI_OPTION 12
-#define NO_INIT_FILE_OPTION 13
-#define NO_INIT_PATH_OPTION 14
-#define NO_JIT_COMPILER_OPTION 15
-#define NO_LINE_EDITING_OPTION 16
-#define NO_SITE_FILE_OPTION 17
-#define PERSIST_OPTION 18
-#define TEXI_MACROS_FILE_OPTION 19
-#define TRADITIONAL_OPTION 20
+#define NO_GUI_OPTION 11
+#define NO_INIT_FILE_OPTION 12
+#define NO_INIT_PATH_OPTION 13
+#define NO_JIT_COMPILER_OPTION 14
+#define NO_LINE_EDITING_OPTION 15
+#define NO_SITE_FILE_OPTION 16
+#define PERSIST_OPTION 17
+#define TEXI_MACROS_FILE_OPTION 18
+#define TRADITIONAL_OPTION 19
 struct option long_opts[] = {
   { "braindead",                no_argument,       0, TRADITIONAL_OPTION },
   { "built-in-docstrings-file", required_argument, 0, BUILT_IN_DOCSTRINGS_FILE_OPTION },
@@ -82,7 +81,6 @@
   { "info-program",             required_argument, 0, INFO_PROG_OPTION },
   { "interactive",              no_argument,       0, 'i' },
   { "line-editing",             no_argument,       0, LINE_EDITING_OPTION },
-  { "no-fork",                  no_argument,       0, NO_FORK_OPTION },
   { "no-gui",                   no_argument,       0, NO_GUI_OPTION },
   { "no-history",               no_argument,       0, 'H' },
   { "no-init-file",             no_argument,       0, NO_INIT_FILE_OPTION },
@@ -129,7 +127,6 @@
   --info-program PROGRAM  Use PROGRAM for reading info files.\n\
   --interactive, -i       Force interactive behavior.\n\
   --line-editing          Force readline use for command-line editing.\n\
-  --no-fork               Don't fork when starting the graphical user interface.\n\
   --no-gui                Disable the graphical user interface.\n\
   --no-history, -H        Don't save commands to the history list\n\
   --no-init-file          Don't read the ~/.octaverc or .octaverc files.\n\
--- a/run-octave.in	Sun Oct 27 08:40:54 2013 -0400
+++ b/run-octave.in	Sun Oct 27 18:47:22 2013 -0400
@@ -78,6 +78,7 @@
   fi
 fi
 
+OCTAVE_BINDIR="$builddir/src" \
 OCTAVE_SITE_INITFILE="$top_srcdir/scripts/startup/main-rcfile" \
 OCTAVE_DEFAULT_QT_SETTINGS="$builddir/libgui/default-qt-settings" \
 OCTAVE_LOCALE_DIR="$builddir/libgui/languages" \
--- a/src/Makefile.am	Sun Oct 27 08:40:54 2013 -0400
+++ b/src/Makefile.am	Sun Oct 27 18:47:22 2013 -0400
@@ -36,23 +36,39 @@
 AM_CXXFLAGS += $(WARN_CXXFLAGS)
 
 EXTRA_DIST = \
+  main.in.cc \
   mkoctfile.in.cc \
   mkoctfile.in.sh \
   octave-config.in.cc \
   octave-config.in.sh
 
-DISTCLEANFILES =
+DISTCLEANFILES = \
+  main.cc
 
 OCTAVE_BINARIES = \
   octave \
   octave-cli
 
+if AMCOND_BUILD_GUI
+  OCTAVE_BINARIES += octave-gui
+endif
+
 OCTAVE_CORE_LIBS = \
   $(top_builddir)/libinterp/liboctinterp.la \
   $(top_builddir)/liboctave/liboctave.la
 
 include ../libgui/link-deps.mk
 
+nodist_octave_SOURCES = main.cc
+
+octave_LDADD = \
+  $(top_builddir)/libgnu/libgnu.la \
+  $(GNULIB_LINK_DEPS)
+
+octave_LDFLAGS = \
+  $(NO_UNDEFINED_LDFLAG) \
+  $(OCTAVE_LINK_OPTS)
+
 octave_cli_SOURCES = main-cli.cc
 
 octave_cli_LDADD = \
@@ -64,25 +80,21 @@
   $(OCTAVE_LINK_OPTS)
 
 if AMCOND_BUILD_GUI
-  octave_SOURCES = main.cc
+  octave_gui_SOURCES = main-gui.cc
   OCTAVE_GUI_LIBS = $(top_builddir)/libgui/liboctgui.la
   OCTAVE_GUI_CPPFLAGS = -I$(top_srcdir)/libgui/src
-else
-  octave_SOURCES = main-cli.cc
-  OCTAVE_GUI_LIBS =
-  OCTAVE_GUI_CPPFLAGS =
 endif
 
-octave_CPPFLAGS = \
+octave_gui_CPPFLAGS = \
   $(AM_CPPFLAGS) \
   $(OCTAVE_GUI_CPPFLAGS)
 
-octave_LDADD = \
+octave_gui_LDADD = \
   $(OCTAVE_GUI_LIBS) \
   $(OCTAVE_CORE_LIBS) \
   $(OCTAVE_GUI_LINK_DEPS)
 
-octave_LDFLAGS = \
+octave_gui_LDFLAGS = \
   $(NO_UNDEFINED_LDFLAG) \
   $(OCTAVE_GUI_LINK_OPTS)
 
@@ -131,6 +143,12 @@
 	chmod a+rx $@
 endif
 
+## main.cc must depend on Makefile.  Calling configure may change
+## default/config values.  However, calling configure will also 
+## regenerate the Makefiles from Makefile.am and trigger the rules below.
+main.cc: main.in.cc Makefile
+	@$(do_subst_default_vals)
+
 install-exec-hook: make-version-links
 
 uninstall-local: remove-version-links
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main-gui.cc	Sun Oct 27 18:47:22 2013 -0400
@@ -0,0 +1,44 @@
+/*
+
+Copyright (C) 2012-2013 John W. Eaton
+
+This file is part of Octave.
+
+Octave 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 3 of the License, or (at your
+option) any later version.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "defaults.h"
+#include "octave.h"
+#include "octave-gui.h"
+#include "sysdep.h"
+
+int
+main (int argc, char **argv)
+{
+  octave_process_command_line (argc, argv);
+
+  sysdep_init ();
+
+  install_defaults ();
+
+  bool start_gui = octave_starting_gui ();
+
+  return octave_start_gui (argc, argv, start_gui);
+}
--- a/src/main.cc	Sun Oct 27 08:40:54 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
-
-Copyright (C) 2012-2013 John W. Eaton
-
-This file is part of Octave.
-
-Octave 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 3 of the License, or (at your
-option) any later version.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "defaults.h"
-#include "octave.h"
-#include "octave-gui.h"
-#include "sysdep.h"
-
-int
-main (int argc, char **argv)
-{
-  int retval = 0;
-
-  octave_process_command_line (argc, argv);
-
-  sysdep_init ();
-
-  install_defaults ();
-
-  if (octave_starting_gui ())
-    retval = octave_start_gui (argc, argv, octave_fork_gui ());
-  else
-    {
-      octave_initialize_interpreter (argc, argv, 0);
-
-      retval = octave_execute_interpreter ();
-    }
-
-  return retval;
-}
-
-
-/*!
-@mainpage Source code documentation for GNU Octave
-
-GNU Octave is a high-level language, primarily intended for numerical
-computations.  It provides a convenient interactive command line
-interface for solving linear and nonlinear problems numerically, and
-for performing other numerical experiments.  It may also be used as a
-batch-oriented language for data processing.
-
-GNU Octave is free software. You may redistribute it and/or modify it
-under the terms of the <a href="http://www.gnu.org/licenses/">GNU
-General Public License</a> as published by the Free Software Foundation.
-
-This is the developer documentation for Octave's own source code. It is
-intended to help for hacking Octave. It may also be useful for
-understanding the Octave API when writing your own .oct files.
-*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main.in.cc	Sun Oct 27 18:47:22 2013 -0400
@@ -0,0 +1,442 @@
+// %NO_EDIT_WARNING%
+/*
+
+Copyright (C) 2012-2013 John W. Eaton
+
+This file is part of Octave.
+
+Octave 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 3 of the License, or (at your
+option) any later version.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+// NOTE: This program is supposed to be a small wrapper that exists
+// primarily to give up the controlling TTY and then exec Octave with
+// its GUI.  It may also execute Octave without the GUI or the command
+// line version of Octave that is not linked with GUI libraries.  So
+// that it remains small, it should NOT depend on or be linked with
+// liboctave or libinterp.
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+#include <cstring>
+
+#include <algorithm>
+#include <iostream>
+#include <string>
+
+#include <sys/wait.h>
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifndef OCTAVE_BINDIR
+#define OCTAVE_BINDIR %OCTAVE_BINDIR%
+#endif
+
+#ifndef OCTAVE_PREFIX
+#define OCTAVE_PREFIX %OCTAVE_PREFIX%
+#endif
+
+typedef void sig_handler (int);
+
+// Forward signals to the GUI process.
+
+static pid_t gui_pid = 0;
+
+static void
+gui_driver_sig_handler (int sig)
+{
+  if (gui_pid > 0)
+    kill (gui_pid, sig);
+}
+
+static sig_handler *
+octave_set_signal_handler (int sig, sig_handler *handler)
+{
+  struct sigaction act, oact;
+
+  act.sa_handler = handler;
+  act.sa_flags = 0;
+
+  gnulib::sigemptyset (&act.sa_mask);
+  gnulib::sigemptyset (&oact.sa_mask);
+
+  gnulib::sigaction (sig, &act, &oact);
+
+  return oact.sa_handler;
+}
+
+static void
+install_signal_handlers (void)
+{
+
+#ifdef SIGINT
+  octave_set_signal_handler (SIGINT, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGBREAK
+  octave_set_signal_handler (SIGBREAK, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGABRT
+  octave_set_signal_handler (SIGABRT, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGALRM
+  octave_set_signal_handler (SIGALRM, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGBUS
+  octave_set_signal_handler (SIGBUS, gui_driver_sig_handler);
+#endif
+
+  // SIGCHLD
+  // SIGCLD
+  // SIGCONT
+
+#ifdef SIGEMT
+  octave_set_signal_handler (SIGEMT, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGFPE
+  octave_set_signal_handler (SIGFPE, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGHUP
+  octave_set_signal_handler (SIGHUP, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGILL
+  octave_set_signal_handler (SIGILL, gui_driver_sig_handler);
+#endif
+
+  // SIGINFO
+  // SIGINT
+
+#ifdef SIGIOT
+  octave_set_signal_handler (SIGIOT, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGLOST
+  octave_set_signal_handler (SIGLOST, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGPIPE
+  octave_set_signal_handler (SIGPIPE, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGPOLL
+  octave_set_signal_handler (SIGPOLL, gui_driver_sig_handler);
+#endif
+
+  // SIGPROF
+  // SIGPWR
+
+#ifdef SIGQUIT
+  octave_set_signal_handler (SIGQUIT, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGSEGV
+  octave_set_signal_handler (SIGSEGV, gui_driver_sig_handler);
+#endif
+
+  // SIGSTOP
+
+#ifdef SIGSYS
+  octave_set_signal_handler (SIGSYS, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGTERM
+  octave_set_signal_handler (SIGTERM, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGTRAP
+  octave_set_signal_handler (SIGTRAP, gui_driver_sig_handler);
+#endif
+
+  // SIGTSTP
+  // SIGTTIN
+  // SIGTTOU
+  // SIGURG
+
+#ifdef SIGUSR1
+  octave_set_signal_handler (SIGUSR1, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGUSR2
+  octave_set_signal_handler (SIGUSR2, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGVTALRM
+  octave_set_signal_handler (SIGVTALRM, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGIO
+  octave_set_signal_handler (SIGIO, gui_driver_sig_handler);
+#endif
+
+  // SIGWINCH
+
+#ifdef SIGXCPU
+  octave_set_signal_handler (SIGXCPU, gui_driver_sig_handler);
+#endif
+
+#ifdef SIGXFSZ
+  octave_set_signal_handler (SIGXFSZ, gui_driver_sig_handler);
+#endif
+
+}
+
+static int
+have_controlling_terminal (void)
+{
+  int retval = 0;
+
+#if ! (defined (__WIN32__) || defined (__APPLE__)) || defined (__CYGWIN__)
+
+#if defined (HAVE_CTERMID)
+  const char *ctty = ctermid (0);
+#else
+  const char *ctty = "/dev/tty";
+#endif
+
+  int fd = gnulib::open (ctty, O_RDWR, 0);
+
+  if (fd >= 0)
+    {
+      gnulib::close (fd);
+
+      retval = 1;
+    }
+
+#endif
+
+  return retval;
+}
+
+// Find the directory where the octave binary is supposed to be
+// installed.
+
+#if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) \
+     && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
+static const char dir_sep_char = '\\';
+#else
+static const char dir_sep_char = '/';
+#endif
+
+static std::string
+octave_getenv (const std::string& name)
+{
+  char *value = ::getenv (name.c_str ());
+
+  return value ? value : "";
+}
+
+static std::string
+get_octave_home (void)
+{
+  std::string oh = octave_getenv ("OCTAVE_HOME");
+
+  return oh.empty () ? std::string (OCTAVE_PREFIX) : oh;
+}
+
+static std::string
+subst_octave_home (const std::string& s)
+{
+  std::string retval;
+
+  std::string octave_home = get_octave_home ();
+
+  std::string prefix = OCTAVE_PREFIX;
+
+  retval = s;
+
+  if (octave_home != prefix)
+    {
+      octave_idx_type len = prefix.length ();
+
+      if (s.substr (0, len) == prefix)
+        retval.replace (0, len, octave_home);
+    }
+
+  if (dir_sep_char != '/')
+    std::replace (retval.begin (), retval.end (), '/', dir_sep_char);
+
+  return retval;
+}
+
+static std::string
+get_octave_bindir (void)
+{
+  // Accept value from the environment literally, but substitute
+  // OCTAVE_HOME in the configuration value OCTAVE_BINDIR in case Octave
+  // has been relocated to some installation directory other than the
+  // one originally configured.
+
+  std::string obd = octave_getenv ("OCTAVE_BINDIR");
+
+  return obd.empty () ? subst_octave_home (std::string (OCTAVE_BINDIR)) : obd;
+}
+
+static int
+octave_exec (const std::string& file, char **argv)
+{
+  execv (file.c_str (), argv);
+
+  std::cerr << "octave: failed to exec '" << file << "'" << std::endl;
+
+  return 1;
+}
+
+static char *
+strsave (const char *s)
+{
+  if (! s)
+    return 0;
+
+  int len = strlen (s);
+  char *tmp = new char [len+1];
+  tmp = strcpy (tmp, s);
+  return tmp;
+}
+
+int
+main (int argc, char **argv)
+{
+  int retval = 0;
+
+  bool start_gui = true;
+  bool cli_only = false;
+
+#if defined (__WIN32__) || defined (__CYGWIN__)
+  bool no_fork_required = true;
+#else
+  bool no_fork_required = false;
+#endif
+
+  std::string octave_bindir = get_octave_bindir ();
+
+  std::string file = octave_bindir + dir_sep_char + "octave-gui";
+
+  char **new_argv = new char * [argc + 1];
+
+  int k = 0;
+  new_argv[k++] = strsave ("octave");
+
+  for (int i = 1; i < argc; i++)
+    {
+      if (! strcmp (argv[i], "--no-gui-libs"))
+        {
+          // Run the version of Octave that is not linked with any GUI
+          // libraries.  It may not be possible to do plotting or any
+          // ui* calls, but it will be a little faster to start and
+          // require less memory.  Don't pass the --no-gui-libs option
+          // on as that option is not recognized by Octave.
+
+          cli_only = true;
+          file = octave_bindir + dir_sep_char + "octave-cli";
+        }
+      else if (! strcmp (argv[i], "--no-gui"))
+        {
+          // If we see this option, then we can just exec octave; we
+          // don't have to create a child process and wait for it to
+          // exit.  But do exec "octave", not "octave-cli", because even
+          // if the --no-gui option is given, we may be asked to do some
+          // plotting or ui* calls.
+
+          start_gui = false;
+          new_argv[k++] = argv[i];
+        }
+      else
+        new_argv[k++] = argv[i];
+    }
+
+  new_argv[k] = 0;
+
+  if (cli_only || no_fork_required
+      || (! start_gui && ! have_controlling_terminal ()))
+    {
+      retval = octave_exec (file, new_argv);
+    }
+  else
+    {
+      install_signal_handlers ();
+
+      gui_pid = fork ();
+
+      if (gui_pid < 0)
+        {
+          std::cerr << "octave: fork failed!" << std::endl;
+
+          retval = 1;
+        }
+      else if (gui_pid == 0)
+        {
+          // Child.
+
+          if (setsid () < 0)
+            {
+              std::cerr << "octave: error calling setsid!" << std::endl;
+
+              retval = 1;
+            }
+
+          retval = octave_exec (file, new_argv);
+        }
+      else
+        {
+          // Parent.  Forward signals to the child while waiting for it
+          // to exit.
+
+          int status;
+
+          while (1)
+            {
+              waitpid (gui_pid, &status, 0);
+
+              if (WIFEXITED (status))
+                {
+                  retval = WIFEXITED (status) ? WEXITSTATUS (status) : 127;
+
+                  break;
+                }
+            }
+        }
+    }
+
+  return retval;
+}
+
+/*!
+@mainpage Source code documentation for GNU Octave
+
+GNU Octave is a high-level language, primarily intended for numerical
+computations.  It provides a convenient interactive command line
+interface for solving linear and nonlinear problems numerically, and
+for performing other numerical experiments.  It may also be used as a
+batch-oriented language for data processing.
+
+GNU Octave is free software. You may redistribute it and/or modify it
+under the terms of the <a href="http://www.gnu.org/licenses/">GNU
+General Public License</a> as published by the Free Software Foundation.
+
+This is the developer documentation for Octave's own source code. It is
+intended to help for hacking Octave. It may also be useful for
+understanding the Octave API when writing your own .oct files.
+*/