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