42 #include <sys/types.h>
45 #ifndef OCTAVE_VERSION
46 #define OCTAVE_VERSION "3.8.0"
49 #ifndef OCTAVE_ARCHLIBDIR
50 #define OCTAVE_ARCHLIBDIR "/usr/local/libexec/octave/3.8.0/exec/x86_64-unknown-linux-gnu"
54 #define OCTAVE_BINDIR "/usr/local/bin"
58 #define OCTAVE_PREFIX "/usr/local"
61 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
63 #define WIN32_LEAN_AND_MEAN
67 w32_get_octave_home (
void)
73 HANDLE h = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE
74 #ifdef TH32CS_SNAPMODULE32
79 if (h != INVALID_HANDLE_VALUE)
81 MODULEENTRY32 mod_info;
83 ZeroMemory (&mod_info,
sizeof (mod_info));
84 mod_info.dwSize =
sizeof (mod_info);
86 if (Module32First (h, &mod_info))
90 std::string mod_name (mod_info.szModule);
92 if (mod_name.find (
"octave") != std::string::npos)
94 bin_dir = mod_info.szExePath;
96 if (bin_dir[bin_dir.length () - 1] !=
'\\')
97 bin_dir.append (1,
'\\');
102 while (Module32Next (h, &mod_info));
108 if (! bin_dir.empty ())
110 size_t pos = bin_dir.rfind (
"\\bin\\");
112 if (pos != std::string::npos)
113 retval = bin_dir.substr (0, pos);
123 #if defined (OCTAVE_USE_WINDOWS_API)
125 #elif defined (HAVE_FRAMEWORK_CARBON)
126 #include <Carbon/Carbon.h>
127 #elif defined (HAVE_X_WINDOWS)
128 #include <X11/Xlib.h>
134 bool dpy_avail =
false;
138 #if defined (OCTAVE_USE_WINDOWS_API)
145 err_msg =
"no graphical display found";
147 #elif defined (HAVE_FRAMEWORK_CARBON)
149 CGDirectDisplayID display = CGMainDisplayID ();
154 err_msg =
"no graphical display found";
156 #elif defined (HAVE_X_WINDOWS)
158 const char *display_name = getenv (
"DISPLAY");
160 if (display_name && *display_name)
162 Display *display = XOpenDisplay (display_name);
166 Screen *screen = DefaultScreenOfDisplay (display);
169 err_msg =
"X11 display has no default screen";
171 XCloseDisplay (display);
176 err_msg =
"unable to open X11 DISPLAY";
179 err_msg =
"X11 DISPLAY environment variable not set";
183 err_msg =
"no graphical display found";
190 #if (defined (HAVE_OCTAVE_GUI) \
191 && ! defined (__WIN32__) || defined (__CYGWIN__))
204 static pid_t gui_pid = 0;
206 static int caught_signal = -1;
209 gui_driver_sig_handler (
int sig)
218 struct sigaction act, oact;
220 act.sa_handler = handler;
223 gnulib::sigemptyset (&act.sa_mask);
224 gnulib::sigemptyset (&oact.sa_mask);
226 gnulib::sigaction (sig, &act, &oact);
228 return oact.sa_handler;
353 have_controlling_terminal (
void)
357 #if defined (HAVE_CTERMID)
358 const char *ctty = ctermid (0);
360 const char *ctty =
"/dev/tty";
363 int fd = gnulib::open (ctty, O_RDWR, 0);
380 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) \
381 && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
384 static const char dir_sep_char =
'/';
390 char *value = ::getenv (name.c_str ());
392 return value ? value :
"";
400 #if defined (__WIN32__) && ! defined (_POSIX_VERSION)
402 oh = w32_get_octave_home ();
419 if (octave_home != prefix)
423 if (s.substr (0, len) == prefix)
424 retval.replace (0, len, octave_home);
427 if (dir_sep_char !=
'/')
461 #if defined (__WIN32__) && ! defined (__CYGWIN__)
486 #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
487 #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
489 prepare_spawn (
char **argv)
496 for (argc = 0; argv[argc] != NULL; argc++)
500 new_argv =
new char* [argc + 1];
503 for (i = 0; i < argc; i++)
505 const char *
string = argv[i];
507 if (
string[0] ==
'\0')
508 new_argv[i] = strdup (
"\"\"");
509 else if (strpbrk (
string, SHELL_SPECIAL_CHARS) != NULL)
511 int quote_around = (strpbrk (
string, SHELL_SPACE_CHARS) != NULL);
513 unsigned int backslashes;
522 for (s =
string; *s !=
'\0'; s++)
526 length += backslashes + 1;
534 length += backslashes + 1;
536 quoted_string =
new char [length + 1];
542 for (s =
string; *s !=
'\0'; s++)
548 for (j = backslashes + 1; j > 0; j--)
560 for (j = backslashes; j > 0; j--)
566 new_argv[i] = quoted_string;
569 new_argv[i] = (
char *)
string;
571 new_argv[argc] = NULL;
576 #endif // __WIN32__ && ! __CYGWIN__
581 #if defined (__WIN32__) && ! defined (__CYGWIN__)
582 argv = prepare_spawn (argv);
583 return _spawnv (_P_WAIT, file.c_str (), argv);
585 execv (file.c_str (), argv);
587 std::cerr <<
"octave: failed to exec '" << file <<
"'" << std::endl;
599 int len = strlen (s);
600 char *tmp =
new char [len+1];
601 tmp = strcpy (tmp, s);
611 bool gui_libs =
false;
619 char **new_argv =
new char * [argc + 1];
623 bool warn_display =
true;
625 for (
int i = 1; i < argc; i++)
627 if (! strcmp (argv[i],
"--force-gui"))
631 #if defined (HAVE_OCTAVE_GUI)
636 file = octave_archlibdir + dir_sep_char +
"octave-gui";
638 file = octave_bindir + dir_sep_char +
"octave-cli-" OCTAVE_VERSION;
640 new_argv[k++] = argv[i];
642 else if (! strcmp (argv[i],
"--no-gui-libs"))
652 else if (! strcmp (argv[i],
"--no-gui"))
662 else if (! strcmp (argv[i],
"--silent") || ! strcmp (argv[i],
"-q")
663 || ! strcmp (argv[i],
"--quiet"))
665 warn_display =
false;
666 new_argv[k++] = argv[i];
669 new_argv[k++] = argv[i];
674 if (gui_libs || start_gui)
676 std::string display_check_err_msg;
683 file = octave_bindir + dir_sep_char +
"octave-cli-" OCTAVE_VERSION;
687 std::cerr <<
"octave: " << display_check_err_msg << std::endl;
688 std::cerr <<
"octave: disabling GUI features" << std::endl;
693 #if defined (__WIN32__) && ! defined (__CYGWIN__)
697 new_argv[0] =
strsave (file.c_str ());
699 #if (defined (HAVE_OCTAVE_GUI) \
700 && ! defined (__WIN32__) || defined (__CYGWIN__))
702 if (gui_libs && start_gui && have_controlling_terminal ())
710 std::cerr <<
"octave: fork failed!" << std::endl;
714 else if (gui_pid == 0)
720 std::cerr <<
"octave: error calling setsid!" << std::endl;
737 if (caught_signal > 0)
739 int sig = caught_signal;
752 std::cerr <<
"octave exited with signal "
753 << WTERMSIG (status) << std::endl;