File: | src/main.cc |
Location: | line 476, column 15 |
Description: | Value stored to 'retval' is never read |
1 | // DO NOT EDIT! Generated automatically from main.in.cc by Make. |
2 | /* |
3 | |
4 | Copyright (C) 2012-2013 John W. Eaton |
5 | |
6 | This file is part of Octave. |
7 | |
8 | Octave is free software; you can redistribute it and/or modify it |
9 | under the terms of the GNU General Public License as published by the |
10 | Free Software Foundation; either version 3 of the License, or (at your |
11 | option) any later version. |
12 | |
13 | Octave is distributed in the hope that it will be useful, but WITHOUT |
14 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
16 | for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with Octave; see the file COPYING. If not, see |
20 | <http://www.gnu.org/licenses/>. |
21 | |
22 | */ |
23 | |
24 | // NOTE: This program is supposed to be a small wrapper that exists |
25 | // primarily to give up the controlling TTY and then exec Octave with |
26 | // its GUI. It may also execute Octave without the GUI or the command |
27 | // line version of Octave that is not linked with GUI libraries. So |
28 | // that it remains small, it should NOT depend on or be linked with |
29 | // liboctave or libinterp. |
30 | |
31 | #ifdef HAVE_CONFIG_H1 |
32 | #include <config.h> |
33 | #endif |
34 | |
35 | #include <cstdlib> |
36 | #include <cstring> |
37 | |
38 | #include <algorithm> |
39 | #include <iostream> |
40 | #include <string> |
41 | |
42 | #include <sys/types.h> |
43 | #include <unistd.h> |
44 | |
45 | #if defined (__WIN32__) && ! defined (_POSIX_VERSION200809L) |
46 | |
47 | #define WIN32_LEAN_AND_MEAN |
48 | #include <tlhelp32.h> |
49 | |
50 | static std::string |
51 | w32_get_octave_home (void) |
52 | { |
53 | std::string retval; |
54 | |
55 | std::string bin_dir; |
56 | |
57 | HANDLE h = CreateToolhelp32Snapshot (TH32CS_SNAPMODULE |
58 | #ifdef TH32CS_SNAPMODULE32 |
59 | | TH32CS_SNAPMODULE32 |
60 | #endif |
61 | , 0); |
62 | |
63 | if (h != INVALID_HANDLE_VALUE) |
64 | { |
65 | MODULEENTRY32 mod_info; |
66 | |
67 | ZeroMemory (&mod_info, sizeof (mod_info)); |
68 | mod_info.dwSize = sizeof (mod_info); |
69 | |
70 | if (Module32First (h, &mod_info)) |
71 | { |
72 | do |
73 | { |
74 | std::string mod_name (mod_info.szModule); |
75 | |
76 | if (mod_name.find ("octave") != std::string::npos) |
77 | { |
78 | bin_dir = mod_info.szExePath; |
79 | |
80 | if (bin_dir[bin_dir.length () - 1] != '\\') |
81 | bin_dir.append (1, '\\'); |
82 | |
83 | break; |
84 | } |
85 | } |
86 | while (Module32Next (h, &mod_info)); |
87 | } |
88 | |
89 | CloseHandle (h); |
90 | } |
91 | |
92 | if (! bin_dir.empty ()) |
93 | { |
94 | size_t pos = bin_dir.rfind ("\\bin\\"); |
95 | |
96 | if (pos != std::string::npos) |
97 | retval = bin_dir.substr (0, pos); |
98 | } |
99 | |
100 | return retval; |
101 | } |
102 | |
103 | #endif |
104 | |
105 | #if (defined (HAVE_OCTAVE_GUI1) \ |
106 | && ! defined (__WIN32__) || defined (__CYGWIN__)) |
107 | |
108 | #include <signal.h> |
109 | #include <fcntl.h> |
110 | |
111 | // This is a liboctave header, but it doesn't include any other Octave |
112 | // headers or declare any functions that are defined in liboctave. |
113 | #include "syswait.h" |
114 | |
115 | typedef void sig_handler (int); |
116 | |
117 | // Forward signals to the GUI process. |
118 | |
119 | static pid_t gui_pid = 0; |
120 | |
121 | static int caught_signal = -1; |
122 | |
123 | static void |
124 | gui_driver_sig_handler (int sig) |
125 | { |
126 | if (gui_pid > 0) |
127 | caught_signal = sig; |
128 | } |
129 | |
130 | static sig_handler * |
131 | octave_set_signal_handler (int sig, sig_handler *handler) |
132 | { |
133 | struct sigaction act, oact; |
134 | |
135 | act.sa_handler__sigaction_handler.sa_handler = handler; |
136 | act.sa_flags = 0; |
137 | |
138 | gnulib::sigemptyset (&act.sa_mask); |
139 | gnulib::sigemptyset (&oact.sa_mask); |
140 | |
141 | gnulib::sigaction (sig, &act, &oact); |
142 | |
143 | return oact.sa_handler__sigaction_handler.sa_handler; |
144 | } |
145 | |
146 | static void |
147 | install_signal_handlers (void) |
148 | { |
149 | |
150 | #ifdef SIGINT2 |
151 | octave_set_signal_handler (SIGINT2, gui_driver_sig_handler); |
152 | #endif |
153 | |
154 | #ifdef SIGBREAK |
155 | octave_set_signal_handler (SIGBREAK, gui_driver_sig_handler); |
156 | #endif |
157 | |
158 | #ifdef SIGABRT6 |
159 | octave_set_signal_handler (SIGABRT6, gui_driver_sig_handler); |
160 | #endif |
161 | |
162 | #ifdef SIGALRM14 |
163 | octave_set_signal_handler (SIGALRM14, gui_driver_sig_handler); |
164 | #endif |
165 | |
166 | #ifdef SIGBUS7 |
167 | octave_set_signal_handler (SIGBUS7, gui_driver_sig_handler); |
168 | #endif |
169 | |
170 | // SIGCHLD |
171 | // SIGCLD |
172 | // SIGCONT |
173 | |
174 | #ifdef SIGEMT |
175 | octave_set_signal_handler (SIGEMT, gui_driver_sig_handler); |
176 | #endif |
177 | |
178 | #ifdef SIGFPE8 |
179 | octave_set_signal_handler (SIGFPE8, gui_driver_sig_handler); |
180 | #endif |
181 | |
182 | #ifdef SIGHUP1 |
183 | octave_set_signal_handler (SIGHUP1, gui_driver_sig_handler); |
184 | #endif |
185 | |
186 | #ifdef SIGILL4 |
187 | octave_set_signal_handler (SIGILL4, gui_driver_sig_handler); |
188 | #endif |
189 | |
190 | // SIGINFO |
191 | // SIGINT |
192 | |
193 | #ifdef SIGIOT6 |
194 | octave_set_signal_handler (SIGIOT6, gui_driver_sig_handler); |
195 | #endif |
196 | |
197 | #ifdef SIGLOST |
198 | octave_set_signal_handler (SIGLOST, gui_driver_sig_handler); |
199 | #endif |
200 | |
201 | #ifdef SIGPIPE13 |
202 | octave_set_signal_handler (SIGPIPE13, gui_driver_sig_handler); |
203 | #endif |
204 | |
205 | #ifdef SIGPOLL29 |
206 | octave_set_signal_handler (SIGPOLL29, gui_driver_sig_handler); |
207 | #endif |
208 | |
209 | // SIGPROF |
210 | // SIGPWR |
211 | |
212 | #ifdef SIGQUIT3 |
213 | octave_set_signal_handler (SIGQUIT3, gui_driver_sig_handler); |
214 | #endif |
215 | |
216 | #ifdef SIGSEGV11 |
217 | octave_set_signal_handler (SIGSEGV11, gui_driver_sig_handler); |
218 | #endif |
219 | |
220 | // SIGSTOP |
221 | |
222 | #ifdef SIGSYS31 |
223 | octave_set_signal_handler (SIGSYS31, gui_driver_sig_handler); |
224 | #endif |
225 | |
226 | #ifdef SIGTERM15 |
227 | octave_set_signal_handler (SIGTERM15, gui_driver_sig_handler); |
228 | #endif |
229 | |
230 | #ifdef SIGTRAP5 |
231 | octave_set_signal_handler (SIGTRAP5, gui_driver_sig_handler); |
232 | #endif |
233 | |
234 | // SIGTSTP |
235 | // SIGTTIN |
236 | // SIGTTOU |
237 | // SIGURG |
238 | |
239 | #ifdef SIGUSR110 |
240 | octave_set_signal_handler (SIGUSR110, gui_driver_sig_handler); |
241 | #endif |
242 | |
243 | #ifdef SIGUSR212 |
244 | octave_set_signal_handler (SIGUSR212, gui_driver_sig_handler); |
245 | #endif |
246 | |
247 | #ifdef SIGVTALRM26 |
248 | octave_set_signal_handler (SIGVTALRM26, gui_driver_sig_handler); |
249 | #endif |
250 | |
251 | #ifdef SIGIO29 |
252 | octave_set_signal_handler (SIGIO29, gui_driver_sig_handler); |
253 | #endif |
254 | |
255 | // SIGWINCH |
256 | |
257 | #ifdef SIGXCPU24 |
258 | octave_set_signal_handler (SIGXCPU24, gui_driver_sig_handler); |
259 | #endif |
260 | |
261 | #ifdef SIGXFSZ25 |
262 | octave_set_signal_handler (SIGXFSZ25, gui_driver_sig_handler); |
263 | #endif |
264 | |
265 | } |
266 | |
267 | static bool |
268 | have_controlling_terminal (void) |
269 | { |
270 | int retval = false; |
271 | |
272 | #if defined (HAVE_CTERMID1) |
273 | const char *ctty = ctermid (0); |
274 | #else |
275 | const char *ctty = "/dev/tty"; |
276 | #endif |
277 | |
278 | int fd = gnulib::open (ctty, O_RDWR02, 0); |
279 | |
280 | if (fd >= 0) |
281 | { |
282 | gnulib::close (fd); |
283 | |
284 | retval = true; |
285 | } |
286 | |
287 | return retval; |
288 | } |
289 | |
290 | #endif |
291 | |
292 | #ifndef OCTAVE_BINDIR"/usr/local/bin" |
293 | #define OCTAVE_BINDIR"/usr/local/bin" "/usr/local/bin" |
294 | #endif |
295 | |
296 | #ifndef OCTAVE_PREFIX"/usr/local" |
297 | #define OCTAVE_PREFIX"/usr/local" "/usr/local" |
298 | #endif |
299 | |
300 | // Find the directory where the octave binary is supposed to be |
301 | // installed. |
302 | |
303 | #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) \ |
304 | && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM1)) |
305 | static const char dir_sep_char = '\\'; |
306 | #else |
307 | static const char dir_sep_char = '/'; |
308 | #endif |
309 | |
310 | static std::string |
311 | octave_getenv (const std::string& name) |
312 | { |
313 | char *value = ::getenv (name.c_str ()); |
314 | |
315 | return value ? value : ""; |
316 | } |
317 | |
318 | static std::string |
319 | get_octave_home (void) |
320 | { |
321 | std::string oh = octave_getenv ("OCTAVE_HOME"); |
322 | |
323 | #if defined (__WIN32__) && ! defined (_POSIX_VERSION200809L) |
324 | if (oh.empty ()) |
325 | oh = w32_get_octave_home (); |
326 | #endif |
327 | |
328 | return oh.empty () ? std::string (OCTAVE_PREFIX"/usr/local") : oh; |
329 | } |
330 | |
331 | static std::string |
332 | subst_octave_home (const std::string& s) |
333 | { |
334 | std::string retval; |
335 | |
336 | std::string octave_home = get_octave_home (); |
337 | |
338 | std::string prefix = OCTAVE_PREFIX"/usr/local"; |
339 | |
340 | retval = s; |
341 | |
342 | if (octave_home != prefix) |
343 | { |
344 | octave_idx_type len = prefix.length (); |
345 | |
346 | if (s.substr (0, len) == prefix) |
347 | retval.replace (0, len, octave_home); |
348 | } |
349 | |
350 | if (dir_sep_char != '/') |
351 | std::replace (retval.begin (), retval.end (), '/', dir_sep_char); |
352 | |
353 | return retval; |
354 | } |
355 | |
356 | static std::string |
357 | get_octave_bindir (void) |
358 | { |
359 | // Accept value from the environment literally, but substitute |
360 | // OCTAVE_HOME in the configuration value OCTAVE_BINDIR in case Octave |
361 | // has been relocated to some installation directory other than the |
362 | // one originally configured. |
363 | |
364 | std::string obd = octave_getenv ("OCTAVE_BINDIR"); |
365 | |
366 | return obd.empty () ? subst_octave_home (std::string (OCTAVE_BINDIR"/usr/local/bin")) : obd; |
367 | } |
368 | |
369 | static int |
370 | octave_exec (const std::string& file, char **argv) |
371 | { |
372 | execv (file.c_str (), argv); |
373 | |
374 | std::cerr << "octave: failed to exec '" << file << "'" << std::endl; |
375 | |
376 | return 1; |
377 | } |
378 | |
379 | static char * |
380 | strsave (const char *s) |
381 | { |
382 | if (! s) |
383 | return 0; |
384 | |
385 | int len = strlen (s); |
386 | char *tmp = new char [len+1]; |
387 | tmp = strcpy (tmp, s); |
388 | return tmp; |
389 | } |
390 | |
391 | int |
392 | main (int argc, char **argv) |
393 | { |
394 | int retval = 0; |
395 | |
396 | #if (defined (HAVE_OCTAVE_GUI1) \ |
397 | && (! defined (__WIN32__) || defined (__CYGWIN__))) |
398 | bool start_gui = true; |
399 | bool gui_libs = true; |
400 | #endif |
401 | |
402 | std::string octave_bindir = get_octave_bindir (); |
403 | |
404 | std::string file = octave_bindir + dir_sep_char; |
405 | |
406 | #if defined (HAVE_OCTAVE_GUI1) |
407 | file += "octave-gui"; |
408 | #else |
409 | file += "octave-cli"; |
410 | #endif |
411 | |
412 | char **new_argv = new char * [argc + 1]; |
413 | |
414 | int k = 0; |
415 | new_argv[k++] = strsave ("octave"); |
416 | |
417 | for (int i = 1; i < argc; i++) |
418 | { |
419 | if (! strcmp (argv[i], "--no-gui-libs")) |
420 | { |
421 | // Run the version of Octave that is not linked with any GUI |
422 | // libraries. It may not be possible to do plotting or any |
423 | // ui* calls, but it will be a little faster to start and |
424 | // require less memory. Don't pass the --no-gui-libs option |
425 | // on as that option is not recognized by Octave. |
426 | |
427 | #if (defined (HAVE_OCTAVE_GUI1) \ |
428 | && ! defined (__WIN32__) || defined (__CYGWIN__)) |
429 | gui_libs = false; |
430 | #endif |
431 | file = octave_bindir + dir_sep_char + "octave-cli"; |
432 | } |
433 | else if (! strcmp (argv[i], "--no-gui")) |
434 | { |
435 | // If we see this option, then we can just exec octave; we |
436 | // don't have to create a child process and wait for it to |
437 | // exit. But do exec "octave", not "octave-cli", because even |
438 | // if the --no-gui option is given, we may be asked to do some |
439 | // plotting or ui* calls. |
440 | |
441 | #if (defined (HAVE_OCTAVE_GUI1) \ |
442 | && ! defined (__WIN32__) || defined (__CYGWIN__)) |
443 | start_gui = false; |
444 | #endif |
445 | new_argv[k++] = argv[i]; |
446 | } |
447 | else |
448 | new_argv[k++] = argv[i]; |
449 | } |
450 | |
451 | new_argv[k] = 0; |
452 | |
453 | #if (defined (HAVE_OCTAVE_GUI1) \ |
454 | && ! defined (__WIN32__) || defined (__CYGWIN__)) |
455 | |
456 | if (gui_libs && start_gui && have_controlling_terminal ()) |
457 | { |
458 | install_signal_handlers (); |
459 | |
460 | gui_pid = fork (); |
461 | |
462 | if (gui_pid < 0) |
463 | { |
464 | std::cerr << "octave: fork failed!" << std::endl; |
465 | |
466 | retval = 1; |
467 | } |
468 | else if (gui_pid == 0) |
469 | { |
470 | // Child. |
471 | |
472 | if (setsid () < 0) |
473 | { |
474 | std::cerr << "octave: error calling setsid!" << std::endl; |
475 | |
476 | retval = 1; |
Value stored to 'retval' is never read | |
477 | } |
478 | |
479 | retval = octave_exec (file, new_argv); |
480 | } |
481 | else |
482 | { |
483 | // Parent. Forward signals to the child while waiting for it |
484 | // to exit. |
485 | |
486 | int status; |
487 | |
488 | while (true) |
489 | { |
490 | WAITPID (gui_pid, &status, 0)waitpid (gui_pid, &status, 0); |
491 | |
492 | if (caught_signal > 0) |
493 | { |
494 | int sig = caught_signal; |
495 | |
496 | caught_signal = -1; |
497 | |
498 | kill (gui_pid, sig); |
499 | } |
500 | else if (WIFEXITED (status)((((*(int *) &(status))) & 0x7f) == 0)) |
501 | { |
502 | retval = WEXITSTATUS (status)((((*(int *) &(status))) & 0xff00) >> 8); |
503 | break; |
504 | } |
505 | else if (WIFSIGNALLED (status)(((status) & 0177) != 0177 && ((status) & 0177 ) != 0)) |
506 | { |
507 | std::cerr << "octave exited with signal " |
508 | << WTERMSIG (status)(((*(int *) &(status))) & 0x7f) << std::endl; |
509 | break; |
510 | } |
511 | } |
512 | } |
513 | } |
514 | else |
515 | retval = octave_exec (file, new_argv); |
516 | |
517 | #else |
518 | |
519 | retval = octave_exec (file, new_argv); |
520 | |
521 | #endif |
522 | |
523 | return retval; |
524 | } |
525 | |
526 | /*! |
527 | @mainpage Source code documentation for GNU Octave |
528 | |
529 | GNU Octave is a high-level language, primarily intended for numerical |
530 | computations. It provides a convenient interactive command line |
531 | interface for solving linear and nonlinear problems numerically, and |
532 | for performing other numerical experiments. It may also be used as a |
533 | batch-oriented language for data processing. |
534 | |
535 | GNU Octave is free software. You may redistribute it and/or modify it |
536 | under the terms of the <a href="http://www.gnu.org/licenses/">GNU |
537 | General Public License</a> as published by the Free Software Foundation. |
538 | |
539 | This is the developer documentation for Octave's own source code. It is |
540 | intended to help for hacking Octave. It may also be useful for |
541 | understanding the Octave API when writing your own .oct files. |
542 | */ |