#include #include #include #include #include #include /* Define to the location of your Octave installation. */ #define OCTAVE_INSTALL_DIR "/usr/local/octave/dev/bin/" /* Choose one of these depending on your system type. */ /* #define OCTAVE_USE_WINDOWS_API 1 */ #define HAVE_FRAMEWORK_CARBON 1 /* #define HAVE_X_WINDOWS 1 */ /* You may also need to link with an appropriate system library, for example, -lX11 on systems with X Windows. */ #if defined (OCTAVE_USE_WINDOWS_API) #include #elif defined (HAVE_FRAMEWORK_CARBON) #include #elif defined (HAVE_X_WINDOWS) #include #endif typedef void sig_handler (int); static pid_t gui_pid = 0; static void gui_driver_sig_handler (int sig) { if (gui_pid > 0) kill (gui_pid, sig); } sig_handler * octave_set_signal_handler (int sig, sig_handler *handler) { struct sigaction act, oact; act.sa_handler = handler; act.sa_flags = 0; sigemptyset (&act.sa_mask); sigemptyset (&oact.sa_mask); sigaction (sig, &act, &oact); return oact.sa_handler; } 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 } void display_exec_info (const char *file, char **argv) { char *arg; fprintf (stderr, "executing:\n\n %s", file); while (arg = *++argv) fprintf (stderr, " %s", arg); fputs ("\n\n", stderr); } int display_available (void) { int have_dpy = 0; #if defined (OCTAVE_USE_WINDOWS_API) HDC hdc = GetDC (0); if (hdc) have_dpy = 1; else fputs ("no graphical display found\n", stderr); #elif defined (HAVE_FRAMEWORK_CARBON) CGDirectDisplayID display = CGMainDisplayID (); if (display) have_dpy = 1; else fputs ("no graphical display found\n", stderr); #elif defined (HAVE_X_WINDOWS) const char *display_name = getenv ("DISPLAY"); if (display_name && *display_name) { Display *display = XOpenDisplay (display_name); if (display) { XCloseDisplay (display); have_dpy = 1; } else fputs ("warning: unable to open X11 DISPLAY", stderr); } else fputs ("warning: X11 DISPLAY environment variable not set", stderr); #else # error "You must define one of the system types." #endif return have_dpy; } int main (int argc, char **argv) { int i, k = 0; int start_gui = display_available (); char *file = OCTAVE_INSTALL_DIR "octave"; char **new_argv = (char **) malloc ((argc + 2) * sizeof (char **)); new_argv[k++] = "octave"; for (i = 1; i < argc; i++) { if (! strcmp (argv[i], "--no-gui")) { start_gui = 0; file = OCTAVE_INSTALL_DIR "octave-cli"; } else new_argv[k++] = argv[i]; } if (start_gui) new_argv[k++] = "--no-fork"; new_argv[k] = 0; if (start_gui) { install_signal_handlers (); display_exec_info (file, new_argv); gui_pid = fork (); if (gui_pid < 0) { fputs ("fork failed!\n", stderr); exit (1); } else if (gui_pid == 0) { /* Child. */ if (setsid () < 0) { fputs ("setsid error\n", stderr); exit (1); } execv (file, new_argv); } else { int status; while (1) { waitpid (gui_pid, &status, 0); if (WIFEXITED (status)) exit (WIFEXITED (status) ? WEXITSTATUS (status) : 127); } } } else { display_exec_info (file, new_argv); execv (file, new_argv); /* FIXME -- check to see whether exec fails? */ } return 0; }