This source file includes following definitions.
- OS_Setup
- sigchld_handler_no_subshell
- init_sigchld
- check_sid
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 #include <config.h>
33
34 #include <locale.h>
35 #include <pwd.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <sys/wait.h>
41 #include <signal.h>
42 #include <unistd.h>
43
44 #include "lib/global.h"
45
46 #include "lib/event.h"
47 #include "lib/tty/tty.h"
48 #include "lib/tty/key.h"
49 #include "lib/tty/mouse.h"
50 #include "lib/skin.h"
51 #include "lib/filehighlight.h"
52 #include "lib/fileloc.h"
53 #include "lib/strutil.h"
54 #include "lib/util.h"
55 #include "lib/vfs/vfs.h"
56
57 #include "filemanager/filemanager.h"
58 #include "filemanager/treestore.h"
59 #include "filemanager/layout.h"
60 #include "filemanager/ext.h"
61 #include "filemanager/command.h"
62 #include "filemanager/panel.h"
63
64 #ifdef USE_INTERNAL_EDIT
65 #include "editor/edit.h"
66 #endif
67
68 #include "vfs/plugins_init.h"
69
70 #include "events_init.h"
71 #include "args.h"
72 #ifdef ENABLE_SUBSHELL
73 #include "subshell/subshell.h"
74 #endif
75 #include "keymap.h"
76 #include "setup.h"
77
78 #include "lib/charsets.h"
79 #include "selcodepage.h"
80
81 #include "consaver/cons.saver.h"
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 static void
99 OS_Setup (void)
100 {
101 mc_shell_init ();
102
103
104
105 const char *datadir_env = g_getenv ("MC_DATADIR");
106
107 if (datadir_env != NULL)
108 mc_global.sysconfig_dir = g_strdup (datadir_env);
109 else
110 mc_global.sysconfig_dir = g_strdup (SYSCONFDIR);
111
112 mc_global.share_data_dir = g_strdup (DATADIR);
113 }
114
115
116
117 static void
118 sigchld_handler_no_subshell (int sig)
119 {
120 #ifdef __linux__
121 int pid, status;
122
123 if (mc_global.tty.console_flag == '\0')
124 return;
125
126
127
128
129
130
131
132
133 pid = waitpid (cons_saver_pid, &status, WUNTRACED | WNOHANG);
134
135 if (pid == cons_saver_pid)
136 {
137 if (WIFSTOPPED (status))
138 {
139
140 kill (pid, SIGCONT);
141 }
142 else
143 {
144
145 handle_console (CONSOLE_DONE);
146 mc_global.tty.console_flag = '\0';
147 }
148 }
149
150 #endif
151
152 (void) sig;
153 }
154
155
156
157 static void
158 init_sigchld (void)
159 {
160 struct sigaction sigchld_action;
161
162 memset (&sigchld_action, 0, sizeof (sigchld_action));
163 sigchld_action.sa_handler =
164 #ifdef ENABLE_SUBSHELL
165 mc_global.tty.use_subshell ? sigchld_handler :
166 #endif
167 sigchld_handler_no_subshell;
168
169 sigemptyset (&sigchld_action.sa_mask);
170
171 #ifdef SA_RESTART
172 sigchld_action.sa_flags = SA_RESTART;
173 #endif
174
175 if (my_sigaction (SIGCHLD, &sigchld_action, NULL) == -1)
176 {
177 #ifdef ENABLE_SUBSHELL
178
179
180
181
182 mc_global.tty.use_subshell = FALSE;
183 #endif
184 }
185 }
186
187
188
189
190
191
192
193
194 static gboolean
195 check_sid (void)
196 {
197 pid_t my_sid, old_sid;
198 const char *sid_str;
199
200 sid_str = getenv ("MC_SID");
201 if (sid_str == NULL)
202 return TRUE;
203
204 old_sid = (pid_t) strtol (sid_str, NULL, 0);
205 if (old_sid == 0)
206 return TRUE;
207
208 my_sid = getsid (0);
209 if (my_sid == -1)
210 return TRUE;
211
212
213 return (old_sid != my_sid);
214 }
215
216
217
218
219
220 int
221 main (int argc, char *argv[])
222 {
223 GError *mcerror = NULL;
224 int exit_code = EXIT_FAILURE;
225 vfs_path_t *tmp_vpath = NULL;
226
227 mc_global.run_from_parent_mc = !check_sid ();
228
229
230 #ifdef HAVE_SETLOCALE
231 (void) setlocale (LC_ALL, "");
232 #endif
233 (void) bindtextdomain (PACKAGE, LOCALEDIR);
234 (void) textdomain (PACKAGE);
235
236
237 str_init_strings (NULL);
238
239 mc_setup_run_mode (argv);
240
241 if (!mc_args_parse (&argc, &argv, "mc", &mcerror))
242 {
243 startup_exit_falure:
244 fprintf (stderr, _ ("Failed to run:\n%s\n"), mcerror->message);
245 g_error_free (mcerror);
246 startup_exit_ok:
247 mc_shell_deinit ();
248 str_uninit_strings ();
249 return exit_code;
250 }
251
252
253
254
255
256
257 mc_global.tty.xterm_flag = tty_check_xterm_compat (mc_args__force_xterm);
258
259
260 OS_Setup ();
261
262 if (!g_path_is_absolute (mc_config_get_home_dir ()))
263 {
264 mc_propagate_error (&mcerror, 0, "%s: %s", _ ("Home directory path is not absolute"),
265 mc_config_get_home_dir ());
266 mc_event_deinit (NULL);
267 goto startup_exit_falure;
268 }
269
270 if (!mc_args_show_info ())
271 {
272 exit_code = EXIT_SUCCESS;
273 goto startup_exit_ok;
274 }
275
276 if (!events_init (&mcerror))
277 goto startup_exit_falure;
278
279 mc_config_init_config_paths (&mcerror);
280 if (mcerror != NULL)
281 {
282 mc_event_deinit (NULL);
283 goto startup_exit_falure;
284 }
285
286 vfs_init ();
287 vfs_plugins_init ();
288
289 load_setup ();
290
291
292 vfs_setup_work_dir ();
293
294
295 const char *tmpdir = mc_tmpdir ();
296
297 tmp_vpath = vfs_path_from_str (tmpdir);
298
299
300
301 if (!mc_setup_by_args (argc, argv, &mcerror))
302 {
303
304
305 vfs_expire (TRUE);
306 (void) mc_rmdir (tmp_vpath);
307 vfs_path_free (tmp_vpath, TRUE);
308
309 vfs_shut ();
310 done_setup ();
311 g_free (saved_other_dir);
312 mc_event_deinit (NULL);
313 goto startup_exit_falure;
314 }
315
316
317
318
319
320 if (mc_global.mc_run_mode == MC_RUN_FULL)
321 {
322 char *buffer;
323 vfs_path_t *vpath;
324
325 buffer = mc_config_get_string (mc_global.panels_config, "Dirs", "other_dir", ".");
326 vpath = vfs_path_from_str (buffer);
327 if (vfs_file_is_local (vpath))
328 saved_other_dir = buffer;
329 else
330 g_free (buffer);
331 vfs_path_free (vpath, TRUE);
332 }
333
334
335
336 init_key ();
337
338
339 handle_console (CONSOLE_INIT);
340
341 #ifdef ENABLE_SUBSHELL
342
343 if (mc_global.mc_run_mode != MC_RUN_FULL && mc_global.run_from_parent_mc)
344 mc_global.tty.use_subshell = FALSE;
345
346 if (mc_global.tty.use_subshell)
347 subshell_get_console_attributes ();
348 #endif
349
350
351 init_sigchld ();
352
353
354 save_stop_handler ();
355
356
357
358 tty_init (!mc_args__nomouse, mc_global.tty.xterm_flag);
359
360
361 load_key_defs ();
362
363 keymap_load (!mc_args__nokeymap);
364
365 #ifdef USE_INTERNAL_EDIT
366 macros_list = g_array_new (TRUE, FALSE, sizeof (macros_t));
367 #endif
368
369 tty_init_colors (mc_global.tty.disable_colors, mc_args__force_colors, COLOR_MAP_SIZE);
370
371 mc_skin_init (NULL, &mcerror);
372
373 mc_error_message (&mcerror, NULL);
374
375 #ifdef ENABLE_SUBSHELL
376
377
378 if (mc_global.tty.use_subshell && mc_global.run_from_parent_mc)
379 {
380 char *text;
381
382 text = g_strdup_printf (_ ("%s\nis already running on this terminal.\n"
383 "Subshell support will be disabled."),
384 PACKAGE_NAME);
385
386 const int quit_mc = query_dialog (_ ("Warning"), text, D_ERROR, 2, _ ("&OK"), _ ("&Quit"));
387
388 g_free (text);
389
390 if (quit_mc != 0)
391 {
392
393 mc_global.midnight_shutdown = TRUE;
394 }
395
396
397 mc_global.tty.use_subshell = FALSE;
398 }
399
400 if (mc_global.tty.use_subshell)
401 init_subshell ();
402 #endif
403
404 if (!mc_global.midnight_shutdown)
405 {
406
407 if (mc_global.tty.console_flag != '\0')
408 handle_console (CONSOLE_SAVE);
409
410 if (mc_global.tty.alternate_plus_minus)
411 application_keypad_mode ();
412
413
414
415 init_mouse ();
416
417
418
419 enable_bracketed_paste ();
420
421
422 mc_prompt = g_strdup ((geteuid () == 0) ? "# " : "$ ");
423 }
424
425
426 if (mc_global.midnight_shutdown)
427 exit_code = EXIT_SUCCESS;
428 else
429 exit_code = do_nc () ? EXIT_SUCCESS : EXIT_FAILURE;
430
431 g_free (mc_prompt);
432
433 disable_bracketed_paste ();
434
435 disable_mouse ();
436
437
438 (void) tree_store_save ();
439
440 keymap_free ();
441
442
443
444 vfs_expire (TRUE);
445 (void) mc_rmdir (tmp_vpath);
446 vfs_path_free (tmp_vpath, TRUE);
447
448
449 vfs_shut ();
450
451 flush_extension_file ();
452
453 mc_skin_deinit ();
454 tty_colors_done ();
455
456 tty_shutdown ();
457
458 done_setup ();
459
460 if (mc_global.tty.console_flag != '\0' && (quit & SUBSHELL_EXIT) == 0)
461 handle_console (CONSOLE_RESTORE);
462 if (mc_global.tty.alternate_plus_minus)
463 numeric_keypad_mode ();
464
465 (void) my_signal (SIGCHLD, SIG_DFL);
466
467 if (mc_global.tty.console_flag != '\0')
468 handle_console (CONSOLE_DONE);
469
470 if (mc_global.mc_run_mode == MC_RUN_FULL && mc_args__last_wd_file != NULL && last_wd_str != NULL
471 && !print_last_revert)
472 {
473 const int last_wd_fd =
474 open (mc_args__last_wd_file, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
475
476 if (last_wd_fd != -1)
477 {
478 MC_UNUSED const ssize_t ret1 = write (last_wd_fd, last_wd_str, strlen (last_wd_str));
479 MC_UNUSED const int ret2 = close (last_wd_fd);
480 }
481 }
482
483 g_free (last_wd_str);
484
485 mc_shell_deinit ();
486
487 done_key ();
488
489 #ifdef USE_INTERNAL_EDIT
490 if (macros_list != NULL)
491 {
492 guint i;
493
494 for (i = 0; i < macros_list->len; i++)
495 {
496 macros_t *macros;
497
498 macros = &g_array_index (macros_list, struct macros_t, i);
499 if (macros != NULL && macros->macro != NULL)
500 (void) g_array_free (macros->macro, TRUE);
501 }
502 (void) g_array_free (macros_list, TRUE);
503 }
504 #endif
505
506 str_uninit_strings ();
507
508 if (mc_global.mc_run_mode != MC_RUN_EDITOR)
509 g_free (mc_run_param0);
510 #ifdef USE_INTERNAL_EDIT
511 else
512 g_list_free_full ((GList *) mc_run_param0, (GDestroyNotify) edit_arg_free);
513 #endif
514
515 g_free (mc_run_param1);
516 g_free (saved_other_dir);
517
518 mc_config_deinit_config_paths ();
519
520 (void) mc_event_deinit (&mcerror);
521 if (mcerror != NULL)
522 {
523 fprintf (stderr, _ ("\nFailed while close:\n%s\n"), mcerror->message);
524 g_error_free (mcerror);
525 exit_code = EXIT_FAILURE;
526 }
527
528 (void) putchar ('\n');
529
530 return exit_code;
531 }
532
533