mirror of
https://github.com/MidnightCommander/mc-old.git
synced 2026-02-02 11:11:36 -08:00
(subshell_chdir): move to src/subshell/common.c, make public.
(do_subshell_chdir): make static. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
@@ -62,7 +62,7 @@
|
||||
#include "src/keymap.h" /* global_keymap_t */
|
||||
#include "src/history.h"
|
||||
#ifdef ENABLE_SUBSHELL
|
||||
#include "src/subshell/subshell.h" /* do_subshell_chdir() */
|
||||
#include "src/subshell/subshell.h" /* subshell_chdir() */
|
||||
#endif
|
||||
|
||||
#include "src/usermenu.h"
|
||||
@@ -3440,20 +3440,6 @@ get_parent_dir_name (const vfs_path_t *cwd_vpath, const vfs_path_t *lwd_vpath)
|
||||
return (p != lwd || IS_PATH_SEP (*p)) ? p + 1 : p;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/** Wrapper for do_subshell_chdir, check for availability of subshell */
|
||||
|
||||
static void
|
||||
subshell_chdir (const vfs_path_t *vpath)
|
||||
{
|
||||
#ifdef ENABLE_SUBSHELL
|
||||
if (mc_global.tty.use_subshell && vfs_current_is_local ())
|
||||
do_subshell_chdir (vpath, FALSE);
|
||||
#else /* ENABLE_SUBSHELL */
|
||||
(void) vpath;
|
||||
#endif /* ENABLE_SUBSHELL */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Changes the current directory of the panel.
|
||||
@@ -3489,7 +3475,9 @@ panel_do_cd_int (WPanel *panel, const vfs_path_t *new_dir_vpath, enum cd_enum cd
|
||||
|
||||
vfs_release_path (olddir_vpath);
|
||||
|
||||
#ifdef ENABLE_SUBSHELL
|
||||
subshell_chdir (panel->cwd_vpath);
|
||||
#endif /* ENABLE_SUBSHELL */
|
||||
|
||||
/* Reload current panel */
|
||||
panel_clean_dir (panel);
|
||||
@@ -3890,8 +3878,10 @@ panel_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *dat
|
||||
cd_error_message (cwd);
|
||||
g_free (cwd);
|
||||
}
|
||||
#ifdef ENABLE_SUBSHELL
|
||||
else
|
||||
subshell_chdir (panel->cwd_vpath);
|
||||
#endif /* ENABLE_SUBSHELL */
|
||||
|
||||
update_xterm_title_path ();
|
||||
update_terminal_cwd ();
|
||||
|
||||
@@ -1309,10 +1309,140 @@ clear_cwd_pipe (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
static void
|
||||
do_subshell_chdir (const vfs_path_t *vpath, gboolean update_prompt)
|
||||
{
|
||||
char *pcwd;
|
||||
|
||||
pcwd = vfs_path_to_str_flags (subshell_get_cwd (), 0, VPF_RECODE);
|
||||
|
||||
if (!(subshell_state == INACTIVE && strcmp (subshell_cwd, pcwd) != 0))
|
||||
{
|
||||
/* We have to repaint the subshell prompt if we read it from
|
||||
* the main program. Please note that in the code after this
|
||||
* if, the cd command that is sent will make the subshell
|
||||
* repaint the prompt, so we don't have to paint it. */
|
||||
if (update_prompt)
|
||||
do_update_prompt ();
|
||||
g_free (pcwd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we are using a shell that doesn't support persistent command buffer, we need to clear
|
||||
* the command prompt before we send the cd command. */
|
||||
if (!use_persistent_buffer)
|
||||
{
|
||||
write_all (mc_global.tty.subshell_pty, "\003", 1);
|
||||
subshell_state = RUNNING_COMMAND;
|
||||
if (mc_global.shell->type != SHELL_FISH)
|
||||
if (!feed_subshell (QUIETLY, TRUE))
|
||||
{
|
||||
subshell_state = ACTIVE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* A quick and dirty fix for fish shell. For some reason, fish does not
|
||||
* execute all the commands sent to it from Midnight Commander :(
|
||||
* An example of such buggy behavior is presented in ticket #4521.
|
||||
* TODO: Find the real cause and fix it "the right way" */
|
||||
if (mc_global.shell->type == SHELL_FISH)
|
||||
{
|
||||
write_all (mc_global.tty.subshell_pty, "\n", 1);
|
||||
subshell_state = RUNNING_COMMAND;
|
||||
feed_subshell (QUIETLY, TRUE);
|
||||
}
|
||||
|
||||
/* The initial space keeps this out of the command history (in bash
|
||||
because we set "HISTCONTROL=ignorespace") */
|
||||
write_all (mc_global.tty.subshell_pty, " cd ", 4);
|
||||
|
||||
if (vpath == NULL)
|
||||
write_all (mc_global.tty.subshell_pty, "/", 1);
|
||||
else
|
||||
{
|
||||
const char *translate;
|
||||
|
||||
translate = vfs_translate_path (vfs_path_as_str (vpath));
|
||||
if (translate == NULL)
|
||||
write_all (mc_global.tty.subshell_pty, ".", 1);
|
||||
else
|
||||
{
|
||||
GString *temp;
|
||||
|
||||
temp = subshell_name_quote (translate);
|
||||
write_all (mc_global.tty.subshell_pty, temp->str, temp->len);
|
||||
g_string_free (temp, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
write_all (mc_global.tty.subshell_pty, "\n", 1);
|
||||
|
||||
subshell_state = RUNNING_COMMAND;
|
||||
if (!feed_subshell (QUIETLY, TRUE))
|
||||
{
|
||||
subshell_state = ACTIVE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (subshell_alive)
|
||||
{
|
||||
gboolean bPathNotEq;
|
||||
|
||||
bPathNotEq = strcmp (subshell_cwd, pcwd) != 0;
|
||||
|
||||
if (bPathNotEq && mc_global.shell->type == SHELL_TCSH)
|
||||
{
|
||||
char rp_subshell_cwd[PATH_MAX];
|
||||
char rp_current_panel_cwd[PATH_MAX];
|
||||
char *p_subshell_cwd, *p_current_panel_cwd;
|
||||
|
||||
p_subshell_cwd = mc_realpath (subshell_cwd, rp_subshell_cwd);
|
||||
p_current_panel_cwd = mc_realpath (pcwd, rp_current_panel_cwd);
|
||||
|
||||
if (p_subshell_cwd == NULL)
|
||||
p_subshell_cwd = subshell_cwd;
|
||||
if (p_current_panel_cwd == NULL)
|
||||
p_current_panel_cwd = pcwd;
|
||||
bPathNotEq = strcmp (p_subshell_cwd, p_current_panel_cwd) != 0;
|
||||
}
|
||||
|
||||
if (bPathNotEq && !DIR_IS_DOT (pcwd))
|
||||
{
|
||||
char *cwd;
|
||||
|
||||
cwd = vfs_path_to_str_flags (subshell_get_cwd (), 0, VPF_STRIP_PASSWORD);
|
||||
vfs_print_message (_("Warning: Cannot change to %s.\n"), cwd);
|
||||
g_free (cwd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Really escape Zsh/Fish history */
|
||||
if (mc_global.shell->type == SHELL_ZSH || mc_global.shell->type == SHELL_FISH)
|
||||
{
|
||||
/* Per Zsh documentation last command prefixed with space lingers in the internal history
|
||||
* until the next command is entered before it vanishes. To make it vanish right away,
|
||||
* type a space and press return.
|
||||
*
|
||||
* Fish shell now also provides the same behavior:
|
||||
* https://github.com/fish-shell/fish-shell/commit/9fdc4f903b8b421b18389a0f290d72cc88c128bb
|
||||
* */
|
||||
write_all (mc_global.tty.subshell_pty, " \n", 2);
|
||||
subshell_state = RUNNING_COMMAND;
|
||||
feed_subshell (QUIETLY, TRUE);
|
||||
}
|
||||
|
||||
update_subshell_prompt = FALSE;
|
||||
|
||||
g_free (pcwd);
|
||||
/* Make sure that MC never stores the CWD in a silly format */
|
||||
/* like /usr////lib/../bin, or the strcmp() above will fail */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** public functions ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/**
|
||||
* Fork the subshell, and set up many, many things.
|
||||
@@ -1695,135 +1825,11 @@ exit_subshell (void)
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/** If it actually changed the directory it returns true */
|
||||
void
|
||||
do_subshell_chdir (const vfs_path_t *vpath, gboolean update_prompt)
|
||||
subshell_chdir (const vfs_path_t *vpath)
|
||||
{
|
||||
char *pcwd;
|
||||
|
||||
pcwd = vfs_path_to_str_flags (subshell_get_cwd (), 0, VPF_RECODE);
|
||||
|
||||
if (!(subshell_state == INACTIVE && strcmp (subshell_cwd, pcwd) != 0))
|
||||
{
|
||||
/* We have to repaint the subshell prompt if we read it from
|
||||
* the main program. Please note that in the code after this
|
||||
* if, the cd command that is sent will make the subshell
|
||||
* repaint the prompt, so we don't have to paint it. */
|
||||
if (update_prompt)
|
||||
do_update_prompt ();
|
||||
g_free (pcwd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If we are using a shell that doesn't support persistent command buffer, we need to clear
|
||||
* the command prompt before we send the cd command. */
|
||||
if (!use_persistent_buffer)
|
||||
{
|
||||
write_all (mc_global.tty.subshell_pty, "\003", 1);
|
||||
subshell_state = RUNNING_COMMAND;
|
||||
if (mc_global.shell->type != SHELL_FISH)
|
||||
if (!feed_subshell (QUIETLY, TRUE))
|
||||
{
|
||||
subshell_state = ACTIVE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* A quick and dirty fix for fish shell. For some reason, fish does not
|
||||
* execute all the commands sent to it from Midnight Commander :(
|
||||
* An example of such buggy behavior is presented in ticket #4521.
|
||||
* TODO: Find the real cause and fix it "the right way" */
|
||||
if (mc_global.shell->type == SHELL_FISH)
|
||||
{
|
||||
write_all (mc_global.tty.subshell_pty, "\n", 1);
|
||||
subshell_state = RUNNING_COMMAND;
|
||||
feed_subshell (QUIETLY, TRUE);
|
||||
}
|
||||
|
||||
/* The initial space keeps this out of the command history (in bash
|
||||
because we set "HISTCONTROL=ignorespace") */
|
||||
write_all (mc_global.tty.subshell_pty, " cd ", 4);
|
||||
|
||||
if (vpath == NULL)
|
||||
write_all (mc_global.tty.subshell_pty, "/", 1);
|
||||
else
|
||||
{
|
||||
const char *translate;
|
||||
|
||||
translate = vfs_translate_path (vfs_path_as_str (vpath));
|
||||
if (translate == NULL)
|
||||
write_all (mc_global.tty.subshell_pty, ".", 1);
|
||||
else
|
||||
{
|
||||
GString *temp;
|
||||
|
||||
temp = subshell_name_quote (translate);
|
||||
write_all (mc_global.tty.subshell_pty, temp->str, temp->len);
|
||||
g_string_free (temp, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
write_all (mc_global.tty.subshell_pty, "\n", 1);
|
||||
|
||||
subshell_state = RUNNING_COMMAND;
|
||||
if (!feed_subshell (QUIETLY, TRUE))
|
||||
{
|
||||
subshell_state = ACTIVE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (subshell_alive)
|
||||
{
|
||||
gboolean bPathNotEq;
|
||||
|
||||
bPathNotEq = strcmp (subshell_cwd, pcwd) != 0;
|
||||
|
||||
if (bPathNotEq && mc_global.shell->type == SHELL_TCSH)
|
||||
{
|
||||
char rp_subshell_cwd[PATH_MAX];
|
||||
char rp_current_panel_cwd[PATH_MAX];
|
||||
char *p_subshell_cwd, *p_current_panel_cwd;
|
||||
|
||||
p_subshell_cwd = mc_realpath (subshell_cwd, rp_subshell_cwd);
|
||||
p_current_panel_cwd = mc_realpath (pcwd, rp_current_panel_cwd);
|
||||
|
||||
if (p_subshell_cwd == NULL)
|
||||
p_subshell_cwd = subshell_cwd;
|
||||
if (p_current_panel_cwd == NULL)
|
||||
p_current_panel_cwd = pcwd;
|
||||
bPathNotEq = strcmp (p_subshell_cwd, p_current_panel_cwd) != 0;
|
||||
}
|
||||
|
||||
if (bPathNotEq && !DIR_IS_DOT (pcwd))
|
||||
{
|
||||
char *cwd;
|
||||
|
||||
cwd = vfs_path_to_str_flags (subshell_get_cwd (), 0, VPF_STRIP_PASSWORD);
|
||||
vfs_print_message (_("Warning: Cannot change to %s.\n"), cwd);
|
||||
g_free (cwd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Really escape Zsh/Fish history */
|
||||
if (mc_global.shell->type == SHELL_ZSH || mc_global.shell->type == SHELL_FISH)
|
||||
{
|
||||
/* Per Zsh documentation last command prefixed with space lingers in the internal history
|
||||
* until the next command is entered before it vanishes. To make it vanish right away,
|
||||
* type a space and press return.
|
||||
*
|
||||
* Fish shell now also provides the same behavior:
|
||||
* https://github.com/fish-shell/fish-shell/commit/9fdc4f903b8b421b18389a0f290d72cc88c128bb
|
||||
* */
|
||||
write_all (mc_global.tty.subshell_pty, " \n", 2);
|
||||
subshell_state = RUNNING_COMMAND;
|
||||
feed_subshell (QUIETLY, TRUE);
|
||||
}
|
||||
|
||||
update_subshell_prompt = FALSE;
|
||||
|
||||
g_free (pcwd);
|
||||
/* Make sure that MC never stores the CWD in a silly format */
|
||||
/* like /usr////lib/../bin, or the strcmp() above will fail */
|
||||
if (mc_global.tty.use_subshell && vfs_current_is_local ())
|
||||
do_subshell_chdir (vpath, FALSE);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
@@ -46,7 +46,7 @@ gboolean flush_subshell (int max_wait_length, int how);
|
||||
gboolean read_subshell_prompt (void);
|
||||
void do_update_prompt (void);
|
||||
gboolean exit_subshell (void);
|
||||
void do_subshell_chdir (const vfs_path_t * vpath, gboolean update_prompt);
|
||||
void subshell_chdir (const vfs_path_t * vpath);
|
||||
void subshell_get_console_attributes (void);
|
||||
void sigchld_handler (int sig);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user