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