Ticket #3748: add support for ksh in subshell

Support Korn shell variants (ksh/oksh/mksh) in the subshell.
This commit is contained in:
d3m3t3r 2024-11-07 13:42:56 +00:00
parent c5b8b69371
commit 4e8d6b9f45
6 changed files with 63 additions and 1 deletions

View File

@ -2406,6 +2406,10 @@ and special keyboard maps in ~/.local/share/mc/inputrc (fallback ~/.inputrc).
.B ash/dash
users (BusyBox or Debian) may specify startup commands in ~/.local/share/mc/ashrc (fallback ~/.profile).
.PP
.B ksh
users (ksh, oksh or mksh) may specify startup commands in ~/.local/share/mc/kshrc
(fallback $ENV or ~/.profile).
.PP
.B zsh
users may specify startup commands in ~/.local/share/mc/.zshrc (fallback ~/.zshrc).
.PP

View File

@ -53,6 +53,7 @@
#define MC_BASHRC_FILE "bashrc"
#define MC_ZSHRC_FILE ".zshrc"
#define MC_ASHRC_FILE "ashrc"
#define MC_KSHRC_FILE "kshrc"
#define MC_INPUTRC_FILE "inputrc"
#define MC_CONFIG_FILE "ini"
#define MC_EXT_FILE "mc.ext.ini"

View File

@ -75,6 +75,7 @@ static const struct
{ &mc_data_str, MC_SKINS_DIR },
{ &mc_data_str, VFS_SHELL_PREFIX },
{ &mc_data_str, MC_ASHRC_FILE },
{ &mc_data_str, MC_KSHRC_FILE },
{ &mc_data_str, MC_BASHRC_FILE },
{ &mc_data_str, MC_INPUTRC_FILE },
{ &mc_data_str, MC_ZSHRC_FILE },

View File

@ -80,6 +80,8 @@ mc_shell_get_installed_in_system (void)
mc_shell->path = g_strdup ("/bin/tcsh");
else if (access ("/bin/csh", X_OK) == 0)
mc_shell->path = g_strdup ("/bin/csh");
else if (access ("/bin/ksh", X_OK) == 0)
mc_shell->path = g_strdup ("/bin/ksh");
/* No fish as fallback because it is so much different from other shells and
* in a way exotic (even though user-friendly by name) that we should not
* present it as a subshell without the user's explicit intention. We rather
@ -189,6 +191,17 @@ mc_shell_recognize_real_path (mc_shell_t *mc_shell)
mc_shell->type = SHELL_ASH_BUSYBOX;
mc_shell->name = mc_shell->path;
}
else if (strstr (mc_shell->path, "/ksh") != NULL
|| strstr (mc_shell->real_path, "/ksh") != NULL
|| strstr (mc_shell->path, "/oksh") != NULL
|| strstr (mc_shell->real_path, "/oksh") != NULL
|| strstr (mc_shell->path, "/mksh") != NULL
|| strstr (mc_shell->real_path, "/mksh") != NULL)
{
/* Korn shell variants */
mc_shell->type = SHELL_KSH;
mc_shell->name = "ksh";
}
else
mc_shell->type = SHELL_NONE;
}
@ -214,6 +227,14 @@ mc_shell_recognize_path (mc_shell_t *mc_shell)
mc_shell->type = SHELL_ASH_BUSYBOX;
mc_shell->name = "ash";
}
else if (strstr (mc_shell->path, "/ksh") != NULL
|| strstr (mc_shell->path, "/oksh") != NULL
|| strstr (mc_shell->path, "/mksh") != NULL
|| getenv ("KSH_VERSION") != NULL)
{
mc_shell->type = SHELL_KSH;
mc_shell->name = "ksh";
}
else
mc_shell->type = SHELL_NONE;
}

View File

@ -18,7 +18,8 @@ typedef enum
SHELL_DASH, /* Debian variant of ash */
SHELL_TCSH,
SHELL_ZSH,
SHELL_FISH
SHELL_FISH,
SHELL_KSH
} shell_type_t;
/*** structures declarations (and typedefs of structures)*****************************************/

View File

@ -365,6 +365,33 @@ init_subshell_child (const char *pty_name)
break;
case SHELL_KSH:
/* Do we have a custom init file ~/.local/share/mc/kshrc? */
init_file = mc_config_get_full_path (MC_KSHRC_FILE);
/* Otherwise use ~/.profile if $ENV is not already set */
if (!exist_file (init_file))
{
g_free (init_file);
init_file = NULL;
if (!g_getenv ("ENV"))
{
init_file = g_strdup (".profile");
}
}
/* Put init file to ENV variable used by ash */
if (init_file)
{
g_setenv ("ENV", init_file, TRUE);
}
/* Make MC's special commands not show up in history */
putenv ((char *) "HISTCONTROL=ignorespace");
break;
case SHELL_ZSH:
/* ZDOTDIR environment variable is the only way to point zsh
* to an other rc file than the default. */
@ -438,6 +465,7 @@ init_subshell_child (const char *pty_name)
case SHELL_ASH_BUSYBOX:
case SHELL_DASH:
case SHELL_TCSH:
case SHELL_KSH:
execl (mc_global.shell->path, mc_global.shell->path, (char *) NULL);
break;
@ -1163,6 +1191,12 @@ init_subshell_precmd (char *precmd, size_t buff_size)
"}; " "PRECMD=precmd; " "PS1='$($PRECMD)$ '\n", subshell_pipe[WRITE]);
break;
case SHELL_KSH:
g_snprintf (precmd, buff_size,
" PS1='$(pwd>&%d; kill -STOP $$)\\u@\\h:\\w\\$ '\n",
subshell_pipe[WRITE]);
break;
case SHELL_ZSH:
g_snprintf (precmd, buff_size,
" mc_print_command_buffer () { printf \"%%s\\\\n\" \"$BUFFER\" >&%d; }\n"