mc/src/main.c

596 lines
17 KiB
C
Raw Normal View History

1998-02-27 07:54:42 +03:00
/* Main program for the Midnight Commander
Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.
1998-02-27 07:54:42 +03:00
Written by: 1994, 1995, 1996, 1997 Miguel de Icaza
1994, 1995 Janne Kukonlehto
1997 Norbert Warmuth
1998-02-27 07:54:42 +03:00
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
1998-02-27 07:54:42 +03:00
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
1998-02-27 07:54:42 +03:00
/** \file main.c
* \brief Source: this is a main module
*/
1998-02-27 07:54:42 +03:00
#include <config.h>
2005-02-08 12:04:03 +03:00
#include <ctype.h>
#include <errno.h>
#include <locale.h>
1998-02-27 07:54:42 +03:00
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
2009-02-06 02:30:45 +03:00
#include <fcntl.h>
2005-02-08 12:04:03 +03:00
#include <sys/types.h>
1998-02-27 07:54:42 +03:00
#include <sys/stat.h>
#include <sys/wait.h>
2005-02-08 12:04:03 +03:00
#include <unistd.h>
#include <pwd.h> /* for username in xterm title */
1998-02-27 07:54:42 +03:00
#include "lib/global.h"
#include "lib/event.h"
#include "lib/tty/tty.h"
#include "lib/tty/key.h" /* For init_key() */
#include "lib/skin.h"
#include "lib/filehighlight.h"
#include "lib/fileloc.h"
#include "lib/strutil.h"
#include "lib/util.h"
#include "lib/vfs/vfs.h" /* vfs_init(), vfs_shut() */
#include "filemanager/midnight.h" /* current_panel */
#include "filemanager/treestore.h" /* tree_store_save */
#include "filemanager/layout.h" /* command_prompt */
#include "filemanager/ext.h" /* flush_extension_file() */
#include "filemanager/command.h" /* cmdline */
#include "vfs/plugins_init.h"
#include "events_init.h"
#include "args.h"
#include "subshell.h"
#include "setup.h" /* load_setup() */
#ifdef HAVE_CHARSET
#include "lib/charsets.h"
#include "selcodepage.h"
#endif /* HAVE_CHARSET */
#include "consaver/cons.saver.h" /* cons_saver_pid */
1998-02-27 07:54:42 +03:00
#include "main.h"
/*** global variables ****************************************************************************/
mc_fhl_t *mc_filehighlight;
/* Set when main loop should be terminated */
int quit = 0;
#ifdef HAVE_CHARSET
/* Numbers of (file I/O) and (input/display) codepages. -1 if not selected */
int default_source_codepage = -1;
char *autodetect_codeset = NULL;
gboolean is_autodetect_codeset_enabled = FALSE;
#endif /* !HAVE_CHARSET */
1998-02-27 07:54:42 +03:00
/* If true use the internal viewer */
int use_internal_view = 1;
/* If set, use the builtin editor */
int use_internal_edit = 1;
char *mc_run_param0 = NULL;
char *mc_run_param1 = NULL;
/* The user's shell */
char *shell = NULL;
/* The prompt */
const char *mc_prompt = NULL;
1998-02-27 07:54:42 +03:00
/* Set to TRUE to suppress printing the last directory */
int print_last_revert = FALSE;
1998-02-27 07:54:42 +03:00
/* If set, then print to the given file the last directory we were at */
char *last_wd_string = NULL;
/* index to record_macro_buf[], -1 if not recording a macro */
int macro_index = -1;
/* macro stuff */
struct macro_action_t record_macro_buf[MAX_MACRO_LENGTH];
GArray *macros_list;
/*** file scope macro definitions ****************************************************************/
1998-02-27 07:54:42 +03:00
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
1998-02-27 07:54:42 +03:00
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
1998-02-27 07:54:42 +03:00
static void
check_codeset (void)
1998-02-27 07:54:42 +03:00
{
const char *current_system_codepage = NULL;
current_system_codepage = str_detect_termencoding ();
#ifdef HAVE_CHARSET
{
const char *_display_codepage;
_display_codepage = get_codepage_id (mc_global.display_codepage);
1998-02-27 07:54:42 +03:00
if (strcmp (_display_codepage, current_system_codepage) != 0)
{
mc_global.display_codepage = get_codepage_index (current_system_codepage);
if (mc_global.display_codepage == -1)
mc_global.display_codepage = 0;
mc_config_set_string (mc_main_config, "Misc", "display_codepage", cp_display);
}
1998-02-27 07:54:42 +03:00
}
#endif
mc_global.utf8_display = str_isutf8 (current_system_codepage);
1998-02-27 07:54:42 +03:00
}
/* --------------------------------------------------------------------------------------------- */
/** POSIX version. The only version we support. */
1998-12-03 00:27:27 +03:00
static void
OS_Setup (void)
1998-02-27 07:54:42 +03:00
{
const char *shell_env = getenv ("SHELL");
if ((shell_env == NULL) || (shell_env[0] == '\0'))
{
struct passwd *pwd;
pwd = getpwuid (geteuid ());
if (pwd != NULL)
shell = g_strdup (pwd->pw_shell);
}
else
shell = g_strdup (shell_env);
if ((shell == NULL) || (shell[0] == '\0'))
{
g_free (shell);
shell = g_strdup ("/bin/sh");
}
1998-02-27 07:54:42 +03:00
}
/* --------------------------------------------------------------------------------------------- */
1998-02-27 07:54:42 +03:00
static void
sigchld_handler_no_subshell (int sig)
{
#ifdef __linux__
1998-02-27 07:54:42 +03:00
int pid, status;
if (!mc_global.tty.console_flag)
return;
1998-02-27 07:54:42 +03:00
/* COMMENT: if it were true that after the call to handle_console(..INIT)
the value of mc_global.tty.console_flag never changed, we could simply not install
this handler at all if (!mc_global.tty.console_flag && !mc_global.tty.use_subshell). */
1998-02-27 07:54:42 +03:00
/* That comment is no longer true. We need to wait() on a sigchld
handler (that's at least what the tarfs code expects currently). */
pid = waitpid (cons_saver_pid, &status, WUNTRACED | WNOHANG);
if (pid == cons_saver_pid)
{
1998-02-27 07:54:42 +03:00
if (WIFSTOPPED (status))
{
/* Someone has stopped cons.saver - restart it */
kill (pid, SIGCONT);
}
else
{
/* cons.saver has died - disable console saving */
handle_console (CONSOLE_DONE);
mc_global.tty.console_flag = '\0';
}
1998-02-27 07:54:42 +03:00
}
2005-02-08 22:59:45 +03:00
/* If we got here, some other child exited; ignore it */
#endif /* __linux__ */
1998-02-27 07:54:42 +03:00
2005-02-08 22:59:45 +03:00
(void) sig;
1998-02-27 07:54:42 +03:00
}
/* --------------------------------------------------------------------------------------------- */
static void
1998-02-27 07:54:42 +03:00
init_sigchld (void)
{
struct sigaction sigchld_action;
sigchld_action.sa_handler =
#ifdef HAVE_SUBSHELL_SUPPORT
mc_global.tty.use_subshell ? sigchld_handler :
#endif /* HAVE_SUBSHELL_SUPPORT */
sigchld_handler_no_subshell;
1998-02-27 07:54:42 +03:00
sigemptyset (&sigchld_action.sa_mask);
#ifdef SA_RESTART
sigchld_action.sa_flags = SA_RESTART;
1998-02-27 07:54:42 +03:00
#else
sigchld_action.sa_flags = 0;
#endif /* !SA_RESTART */
1998-02-27 07:54:42 +03:00
if (sigaction (SIGCHLD, &sigchld_action, NULL) == -1)
{
#ifdef HAVE_SUBSHELL_SUPPORT
/*
* This may happen on QNX Neutrino 6, where SA_RESTART
* is defined but not implemented. Fallback to no subshell.
*/
mc_global.tty.use_subshell = FALSE;
#endif /* HAVE_SUBSHELL_SUPPORT */
}
}
1998-02-27 07:54:42 +03:00
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
int
do_cd (const char *new_dir, enum cd_enum exact)
{
gboolean res;
res = do_panel_cd (current_panel, new_dir, exact);
#if HAVE_CHARSET
if (res)
{
vfs_path_t *vpath = vfs_path_from_str (current_panel->cwd);
vfs_path_element_t *path_element = vfs_path_get_by_index (vpath, -1);
if (path_element->encoding != NULL)
current_panel->codepage = get_codepage_index (path_element->encoding);
else
current_panel->codepage = SELECT_CHARSET_NO_TRANSLATE;
vfs_path_free (vpath);
}
#endif /* HAVE_CHARSET */
return res ? 1 : 0;
}
/* --------------------------------------------------------------------------------------------- */
#ifdef HAVE_SUBSHELL_SUPPORT
int
load_prompt (int fd, void *unused)
{
(void) fd;
(void) unused;
if (!read_subshell_prompt ())
return 0;
/* Don't actually change the prompt if it's invisible */
if (((Dlg_head *) top_dlg->data == midnight_dlg) && command_prompt)
{
char *tmp_prompt;
int prompt_len;
tmp_prompt = strip_ctrl_codes (subshell_prompt);
prompt_len = str_term_width1 (tmp_prompt);
/* Check for prompts too big */
if (COLS > 8 && prompt_len > COLS - 8)
{
prompt_len = COLS - 8;
tmp_prompt[prompt_len] = '\0';
}
mc_prompt = tmp_prompt;
label_set_text (the_prompt, mc_prompt);
input_set_origin ((WInput *) cmdline, prompt_len, COLS - prompt_len);
/* since the prompt has changed, and we are called from one of the
* tty_get_event channels, the prompt updating does not take place
* automatically: force a cursor update and a screen refresh
*/
update_cursor (midnight_dlg);
mc_refresh ();
}
update_subshell_prompt = TRUE;
return 0;
}
#endif /* HAVE_SUBSHELL_SUPPORT */
/* --------------------------------------------------------------------------------------------- */
/** Show current directory in the xterm title */
void
update_xterm_title_path (void)
{
/* TODO: share code with midnight_get_title () */
const char *path;
char host[BUF_TINY];
char *p;
struct passwd *pw = NULL;
char *login = NULL;
int res = 0;
if (mc_global.tty.xterm_flag && xterm_title)
{
path = strip_home_and_password (current_panel->cwd);
res = gethostname (host, sizeof (host));
if (res)
{ /* On success, res = 0 */
host[0] = '\0';
}
else
{
host[sizeof (host) - 1] = '\0';
}
pw = getpwuid (getuid ());
if (pw)
{
login = g_strdup_printf ("%s@%s", pw->pw_name, host);
}
else
{
login = g_strdup (host);
}
p = g_strdup_printf ("mc [%s]:%s", login, path);
fprintf (stdout, "\33]0;%s\7", str_term_form (p));
g_free (login);
g_free (p);
if (!alternate_plus_minus)
numeric_keypad_mode ();
fflush (stdout);
}
}
/* --------------------------------------------------------------------------------------------- */
int
main (int argc, char *argv[])
1998-02-27 07:54:42 +03:00
{
GError *error = NULL;
gboolean isInitialized;
/* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */
setlocale (LC_ALL, "");
bindtextdomain ("mc", LOCALEDIR);
textdomain ("mc");
if (!events_init (&error))
{
fprintf (stderr, _("Failed to run:\n%s\n"), error->message);
g_error_free (error);
(void) mc_event_deinit (NULL);
exit (EXIT_FAILURE);
}
/* Set up temporary directory */
mc_tmpdir ();
1998-02-27 07:54:42 +03:00
OS_Setup ();
str_init_strings (NULL);
/* Initialize and create home directories */
/* do it after the screen library initialization to show the error message */
mc_config_init_config_paths (&error);
if (error == NULL && mc_config_deprecated_dir_present ())
mc_config_migrate_from_old_place (&error);
vfs_init ();
vfs_plugins_init ();
vfs_setup_work_dir ();
if (!mc_args_handle (argc, argv, "mc"))
exit (EXIT_FAILURE);
/* check terminal type
* $TEMR must be set and not empty
* mc_global.tty.xterm_flag is used in init_key() and tty_init()
* Do this after mc_args_handle() where mc_args__force_xterm is set up.
*/
mc_global.tty.xterm_flag = tty_check_term (mc_args__force_xterm);
/* NOTE: This has to be called before tty_init or whatever routine
1998-02-27 07:54:42 +03:00
calls any define_sequence */
init_key ();
/* Must be done before installing the SIGCHLD handler [[FIXME]] */
handle_console (CONSOLE_INIT);
#ifdef HAVE_SUBSHELL_SUPPORT
/* Don't use subshell when invoked as viewer or editor */
if (mc_global.mc_run_mode != MC_RUN_FULL)
mc_global.tty.use_subshell = FALSE;
if (mc_global.tty.use_subshell)
subshell_get_console_attributes ();
#endif /* HAVE_SUBSHELL_SUPPORT */
1998-02-27 07:54:42 +03:00
/* Install the SIGCHLD handler; must be done before init_subshell() */
init_sigchld ();
1998-02-27 07:54:42 +03:00
/* We need this, since ncurses endwin () doesn't restore the signals */
save_stop_handler ();
/* Must be done before init_subshell, to set up the terminal size: */
/* FIXME: Should be removed and LINES and COLS computed on subshell */
tty_init (!mc_args__nomouse, mc_global.tty.xterm_flag);
1998-02-27 07:54:42 +03:00
load_setup ();
/* start check mc_global.display_codepage and mc_global.source_codepage */
check_codeset ();
/* Removing this from the X code let's us type C-c */
load_key_defs ();
load_keymap_defs (!mc_args__nokeymap);
macros_list = g_array_new (TRUE, FALSE, sizeof (macros_t));
tty_init_colors (mc_global.tty.disable_colors, mc_args__force_colors);
{
GError *error2 = NULL;
isInitialized = mc_skin_init (&error2);
mc_filehighlight = mc_fhl_new (TRUE);
dlg_set_default_colors ();
if (!isInitialized)
{
message (D_ERROR, _("Warning"), "%s", error2->message);
g_error_free (error2);
error2 = NULL;
}
}
if (error != NULL)
{
clang: fixed useful warnings (-Wformat related) ../../mc/edit/editcmd.c:2519:50: error: field precision should have type 'int', but argument has type 'gsize' (aka 'unsigned long') [-Wformat] match_expr = g_strdup_printf ("(^|\\s+|\\b)%.*s[^\\s\\.=\\+\\[\\]\\(\\)\\,\\;\\:\\\"\\'\\-\\?\\/\\|\\\\\\{\\}\\*\\&\\^\\%%\\$#@\\!]+", word_len, bufpos); ^ ~~~~~~~~ ../../mc/edit/editcmd.c:2700:38: error: field precision should have type 'int', but argument has type 'gsize' (aka 'unsigned long') [-Wformat] match_expr = g_strdup_printf ("%.*s", word_len, bufpos); ^ ~~~~~~~~ 2 diagnostics generated. make[2]: *** [editcmd.o] Error 1 make[2]: Target `all' not remade because of errors. ../../../mc/src/mcconfig/common.c:71:74: error: format string is not a string literal (potentially insecure) [-Wformat-security] g_propagate_error (error, g_error_new (mc_main_error_quark() ,0, strerror(errno))); ^~~~~~~~~~~~~~~ ../../../mc/src/mcconfig/common.c:83:74: error: format string is not a string literal (potentially insecure) [-Wformat-security] g_propagate_error (error, g_error_new (mc_main_error_quark() ,0, strerror(errno))); ^~~~~~~~~~~~~~~ 2 diagnostics generated. make[3]: *** [libmcconfig_la-common.lo] Error 1 make[3]: Target `all' not remade because of errors. ../../mc/src/main.c:2165:41: error: format string is not a string literal (potentially insecure) [-Wformat-security] message (D_ERROR, _("Warning"), error->message); ^~~~~~~~~~~~~~ 1 diagnostic generated. Signed-off-by: Sergei Trofimovich <slyfox@inbox.ru>
2009-12-06 16:32:16 +03:00
message (D_ERROR, _("Warning"), "%s", error->message);
g_error_free (error);
error = NULL;
}
#ifdef HAVE_SUBSHELL_SUPPORT
/* Done here to ensure that the subshell doesn't */
/* inherit the file descriptors opened below, etc */
if (mc_global.tty.use_subshell)
init_subshell ();
1998-02-27 07:54:42 +03:00
#endif /* HAVE_SUBSHELL_SUPPORT */
1998-02-27 07:54:42 +03:00
/* Also done after init_subshell, to save any shell init file messages */
if (mc_global.tty.console_flag)
handle_console (CONSOLE_SAVE);
Wed Apr 1 00:15:30 1998 Norbert Warmuth <k3190@fh-sw.de> * key.c, key.h (numeric_keypad_mode, application_keypad_mode): New functions which encapsulate two hardcoded escape sequences from main.c. * main.c (main): Use the two new functions from key.c * main.c, screen.c: Moved all file selection keys from the default keymap to the keymap for panels in listing mode. Changed *_selection_cmd to *_selection_cmd_panel in panel_keymap (functions in panel_keymap get a WPanel * as first parameter, i.e. the indirection with cpanel isn't necessary). * main.c (midnight_callback): Keys '*' and '-' were not treated when only_leading_plus_minus==0; Optimized the if-clauses a little bit (i.e. removed duplicate checks). More optimation is possible but it would make the whole stuff completly unreadable. * key.c (correct_key_code): KP_ADD, KP_SUBTRACT and KP_MULTIPLY will be translated to +, - and * only if the option alternate_plus_minus is turned off. * learn.c (learn_keys): Turn alternate_plus_minus temporarily on to avoid translation of KP_ADD, KP_SUBTRACT and KP_MULTIPLY in correct_key_code/make sure keypad is in application mode (makes it possible to learn this keys). * cmd.c (reverse_selection_cmd_panel): New function (renamed from reverse_selection_cmd, takes a WPanel * as parameter, references to cpanel changed to panel/the passed parameter). reverse_selection_cmd now simply calls this function with cpanel. This pair was missing among the *_selection_cmd* functions. * cmd.h: Added function prototypes.
1998-04-01 02:36:24 +04:00
if (alternate_plus_minus)
application_keypad_mode ();
These are a bunch of changes to fix CORBA and session management. They are almost complete (i.e. to handle all nitty gritty cases), but they seem to be working OK right now. SM should be much more stable now. Please tell me if you find any weird behavior - Federico 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * gdesktop-icon.c (desktop_icon_realize): Remove the WM_CLIENT_LEADER property from icon windows so that window managers will not store SM information for them. * gnome-open-dialog.c: Added missing #includes. * gdesktop-init.c (desktop_init_at): Removed an unused variable. * gdesktop.h: Added some missing prototypes. * gmain.h: Added some missing prototypes. * Makefile.in: Added gsession.[ch] to the list of sources. * gmain.c (create_panels): Consider whether we have a CORBA server and session management. * gdesktop.c: #include "gdesktop-init.h" * gdesktop.c: Added a missing cast to GNOME_DIALOG. * gmain.c (create_panels): Removed the run_desktop global variable. * glayout.c (create_container): Set the wmclass of the panel to include its unique ID. * gsession.[ch]: New file with the functions that deal with session management. * glayout.c (gnome_exit): Use session_set_restart(). * gcorba.c (corba_init): Now returns an int with an error value. (corba_init_server): Initialize the server properly. Fixed all the object implementation code. (corba_create_window): New function used to create a window with the CORBA server. * gmain.c (gnome_check_super_user): Now the check for running as root is done here. There should be no GUI code in src/. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * dlg.c (dlg_run_done): Do not call the callback of a NULL current widget. * setup.h: Added missing prototype for setup_init(). * filegui.c (check_progress_buttons): Added a missing return value. * dlg.c (remove_widget): Added a missing return value. * main.c: Removed the global directory_list variable. Removed the main_corba_register_server() function. * main.h: Removed the global run_desktop variable. * panel.h: Now the panel structure has a unique numerical ID used for session management. * screen.c (panel_new): Maintain a unique ID for each panel. * main.c (maybe_display_linksdir): Handle display of the desktop init dir here. (main): Call gnome_check_super_user(). (init_corba_with_args): Call corba_init_server(). * main.c (init_corba_with_args): Do CORBA initialization here. Also removed the global force_activation option. 1999-03-30 Federico Mena Quintero <federico@nuclecu.unam.mx> * vfs.c (vfs_add_current_stamps): Only do stamping of the panels if they exist. * mcserv.c: #include <sys/wait.h> (get_client): Put `#ifdef __EMX__' around an otherwise-unused variable. * utilvfs.c (vfs_split_url): Fix NULL <-> 0 confusion when comparing characters. * ftpfs.c (retrieve_dir): Removed unused variable dot_dot_found. * extfs.c (extfs_init): Assign `key' to c, not `&key'.
1999-03-30 10:09:56 +04:00
2001-09-08 01:15:04 +04:00
#ifdef HAVE_SUBSHELL_SUPPORT
if (mc_global.tty.use_subshell)
{
mc_prompt = strip_ctrl_codes (subshell_prompt);
if (mc_prompt == NULL)
mc_prompt = (geteuid () == 0) ? "# " : "$ ";
}
else
#endif /* HAVE_SUBSHELL_SUPPORT */
mc_prompt = (geteuid () == 0) ? "# " : "$ ";
1998-02-27 07:54:42 +03:00
/* Program main loop */
if (!mc_global.widget.midnight_shutdown)
do_nc ();
/* Save the tree store */
tree_store_save ();
free_keymap_defs ();
1998-02-27 07:54:42 +03:00
/* Virtual File System shutdown */
vfs_shut ();
flush_extension_file (); /* does only free memory */
1998-02-27 07:54:42 +03:00
mc_fhl_free (&mc_filehighlight);
mc_skin_deinit ();
tty_colors_done ();
tty_shutdown ();
1998-02-27 07:54:42 +03:00
done_setup ();
if (mc_global.tty.console_flag && (quit & SUBSHELL_EXIT) == 0)
handle_console (CONSOLE_RESTORE);
Wed Apr 1 00:15:30 1998 Norbert Warmuth <k3190@fh-sw.de> * key.c, key.h (numeric_keypad_mode, application_keypad_mode): New functions which encapsulate two hardcoded escape sequences from main.c. * main.c (main): Use the two new functions from key.c * main.c, screen.c: Moved all file selection keys from the default keymap to the keymap for panels in listing mode. Changed *_selection_cmd to *_selection_cmd_panel in panel_keymap (functions in panel_keymap get a WPanel * as first parameter, i.e. the indirection with cpanel isn't necessary). * main.c (midnight_callback): Keys '*' and '-' were not treated when only_leading_plus_minus==0; Optimized the if-clauses a little bit (i.e. removed duplicate checks). More optimation is possible but it would make the whole stuff completly unreadable. * key.c (correct_key_code): KP_ADD, KP_SUBTRACT and KP_MULTIPLY will be translated to +, - and * only if the option alternate_plus_minus is turned off. * learn.c (learn_keys): Turn alternate_plus_minus temporarily on to avoid translation of KP_ADD, KP_SUBTRACT and KP_MULTIPLY in correct_key_code/make sure keypad is in application mode (makes it possible to learn this keys). * cmd.c (reverse_selection_cmd_panel): New function (renamed from reverse_selection_cmd, takes a WPanel * as parameter, references to cpanel changed to panel/the passed parameter). reverse_selection_cmd now simply calls this function with cpanel. This pair was missing among the *_selection_cmd* functions. * cmd.h: Added function prototypes.
1998-04-01 02:36:24 +04:00
if (alternate_plus_minus)
numeric_keypad_mode ();
1998-02-27 07:54:42 +03:00
signal (SIGCHLD, SIG_DFL); /* Disable the SIGCHLD handler */
if (mc_global.tty.console_flag)
handle_console (CONSOLE_DONE);
if (mc_global.mc_run_mode == MC_RUN_FULL && mc_args__last_wd_file != NULL
&& last_wd_string != NULL && !print_last_revert)
{
int last_wd_fd;
last_wd_fd = open (mc_args__last_wd_file, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL,
S_IRUSR | S_IWUSR);
if (last_wd_fd != -1)
{
ssize_t ret1;
int ret2;
ret1 = write (last_wd_fd, last_wd_string, strlen (last_wd_string));
ret2 = close (last_wd_fd);
}
1998-02-27 07:54:42 +03:00
}
g_free (last_wd_string);
1998-02-27 07:54:42 +03:00
g_free (shell);
1998-02-27 07:54:42 +03:00
done_key ();
if (macros_list != NULL)
{
guint i;
macros_t *macros;
for (i = 0; i < macros_list->len; i++)
{
macros = &g_array_index (macros_list, struct macros_t, i);
if (macros != NULL && macros->macro != NULL)
g_array_free (macros->macro, FALSE);
}
g_array_free (macros_list, TRUE);
}
str_uninit_strings ();
g_free (mc_run_param0);
g_free (mc_run_param1);
mc_event_deinit (&error);
mc_config_deinit_config_paths ();
if (error != NULL)
{
fprintf (stderr, _("\nFailed while close:\n%s\n"), error->message);
g_error_free (error);
exit (EXIT_FAILURE);
}
putchar ('\n'); /* Hack to make shell's prompt start at left of screen */
1998-02-27 07:54:42 +03:00
return 0;
}
/* --------------------------------------------------------------------------------------------- */